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");
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. */
}
}
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) {
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;
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, \
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
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;
{
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. */
}
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);
/* 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);
}
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));
}
}
}
- 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);
}
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);
{
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);
{
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. */
/* 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++) {
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. */
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;