Skip to content

Commit

Permalink
'nresults' moved into 'callstatus'
Browse files Browse the repository at this point in the history
That gives us more free bits in 'callstatus', for future use.
  • Loading branch information
roberto-ieru committed Jul 21, 2024
1 parent f407b3c commit 15231d4
Show file tree
Hide file tree
Showing 6 changed files with 79 additions and 62 deletions.
4 changes: 1 addition & 3 deletions lapi.c
Original file line number Diff line number Diff line change
Expand Up @@ -1103,7 +1103,7 @@ LUA_API int lua_pcallk (lua_State *L, int nargs, int nresults, int errfunc,
ci->u2.funcidx = cast_int(savestack(L, c.func));
ci->u.c.old_errfunc = L->errfunc;
L->errfunc = func;
setoah(ci->callstatus, L->allowhook); /* save value of 'allowhook' */
setoah(ci, L->allowhook); /* save value of 'allowhook' */
ci->callstatus |= CIST_YPCALL; /* function can do error recovery */
luaD_call(L, c.func, nresults); /* do the call */
ci->callstatus &= ~CIST_YPCALL;
Expand Down Expand Up @@ -1280,11 +1280,9 @@ LUA_API int lua_next (lua_State *L, int idx) {


LUA_API void lua_toclose (lua_State *L, int idx) {
int nresults;
StkId o;
lua_lock(L);
o = index2stack(L, idx);
nresults = L->ci->nresults;
api_check(L, L->tbclist.p < o, "given index below or equal a marked one");
luaF_newtbcupval(L, o); /* create new to-be-closed upvalue */
L->ci->callstatus |= CIST_CLSRET; /* mark that function has TBC slots */
Expand Down
4 changes: 2 additions & 2 deletions ldebug.c
Original file line number Diff line number Diff line change
Expand Up @@ -346,13 +346,13 @@ static int auxgetinfo (lua_State *L, const char *what, lua_Debug *ar,
ar->nparams = 0;
}
else {
ar->isvararg = f->l.p->flag & PF_ISVARARG;
ar->isvararg = (f->l.p->flag & PF_ISVARARG) ? 1 : 0;
ar->nparams = f->l.p->numparams;
}
break;
}
case 't': {
ar->istailcall = (ci) ? ci->callstatus & CIST_TAIL : 0;
ar->istailcall = (ci != NULL && (ci->callstatus & CIST_TAIL));
break;
}
case 'n': {
Expand Down
72 changes: 38 additions & 34 deletions ldo.c
Original file line number Diff line number Diff line change
Expand Up @@ -452,16 +452,31 @@ static StkId tryfuncTM (lua_State *L, StkId func) {
}


/* Generic case for 'moveresult */
l_sinline void genmoveresults (lua_State *L, StkId res, int nres,
int wanted) {
StkId firstresult = L->top.p - nres; /* index of first result */
int i;
if (nres > wanted) /* extra results? */
nres = wanted; /* don't need them */
for (i = 0; i < nres; i++) /* move all results to correct place */
setobjs2s(L, res + i, firstresult + i);
for (; i < wanted; i++) /* complete wanted number of results */
setnilvalue(s2v(res + i));
L->top.p = res + wanted; /* top points after the last result */
}


/*
** Given 'nres' results at 'firstResult', move 'wanted' of them to 'res'.
** Handle most typical cases (zero results for commands, one result for
** expressions, multiple results for tail calls/single parameters)
** separated.
** Given 'nres' results at 'firstResult', move 'fwanted-1' of them
** to 'res'. Handle most typical cases (zero results for commands,
** one result for expressions, multiple results for tail calls/single
** parameters) separated. The flag CIST_CLSRET in 'fwanted', if set,
** forces the swicth to go to the default case.
*/
l_sinline void moveresults (lua_State *L, StkId res, int nres, int wanted) {
StkId firstresult;
int i;
switch (wanted) { /* handle typical cases separately */
l_sinline void moveresults (lua_State *L, StkId res, int nres,
l_uint32 fwanted) {
switch (fwanted) { /* handle typical cases separately */
case 0 + 1: /* no values needed */
L->top.p = res;
return;
Expand All @@ -473,12 +488,11 @@ l_sinline void moveresults (lua_State *L, StkId res, int nres, int wanted) {
L->top.p = res + 1;
return;
case LUA_MULTRET + 1:
wanted = nres; /* we want all results */
genmoveresults(L, res, nres, nres); /* we want all results */
break;
default: /* two/more results and/or to-be-closed variables */
if (!(wanted & CIST_CLSRET))
wanted--;
else { /* to-be-closed variables? */
default: { /* two/more results and/or to-be-closed variables */
int wanted = get_nresults(fwanted);
if (fwanted & CIST_CLSRET) { /* to-be-closed variables? */
L->ci->u2.nres = nres;
res = luaF_close(L, res, CLOSEKTOP, 1);
L->ci->callstatus &= ~CIST_CLSRET;
Expand All @@ -487,21 +501,13 @@ l_sinline void moveresults (lua_State *L, StkId res, int nres, int wanted) {
rethook(L, L->ci, nres);
res = restorestack(L, savedres); /* hook can move stack */
}
wanted = (wanted & ~CIST_CLSRET) - 1;
if (wanted == LUA_MULTRET)
wanted = nres; /* we want all results */
}
genmoveresults(L, res, nres, wanted);
break;
}
}
/* generic case */
firstresult = L->top.p - nres; /* index of first result */
if (nres > wanted) /* extra results? */
nres = wanted; /* don't need them */
for (i = 0; i < nres; i++) /* move all results to correct place */
setobjs2s(L, res + i, firstresult + i);
for (; i < wanted; i++) /* complete wanted number of results */
setnilvalue(s2v(res + i));
L->top.p = res + wanted; /* top points after the last result */
}


Expand All @@ -512,13 +518,11 @@ l_sinline void moveresults (lua_State *L, StkId res, int nres, int wanted) {
** that.
*/
void luaD_poscall (lua_State *L, CallInfo *ci, int nres) {
int wanted = ci->nresults + 1;
if (ci->callstatus & CIST_CLSRET)
wanted |= CIST_CLSRET; /* don't check hook in this case */
else if (l_unlikely(L->hookmask))
l_uint32 fwanted = ci->callstatus & (CIST_CLSRET | CIST_NRESULTS);
if (l_unlikely(L->hookmask) && !(fwanted & CIST_CLSRET))
rethook(L, ci, nres);
/* move results to proper place */
moveresults(L, ci->func.p, nres, wanted);
moveresults(L, ci->func.p, nres, fwanted);
/* function cannot be in any of these cases when returning */
lua_assert(!(ci->callstatus &
(CIST_HOOKED | CIST_YPCALL | CIST_FIN | CIST_TRAN | CIST_CLSRET)));
Expand All @@ -530,12 +534,12 @@ void luaD_poscall (lua_State *L, CallInfo *ci, int nres) {
#define next_ci(L) (L->ci->next ? L->ci->next : luaE_extendCI(L))


l_sinline CallInfo *prepCallInfo (lua_State *L, StkId func, int nret,
int mask, StkId top) {
l_sinline CallInfo *prepCallInfo (lua_State *L, StkId func, int nresults,
l_uint32 mask, StkId top) {
CallInfo *ci = L->ci = next_ci(L); /* new frame */
ci->func.p = func;
ci->nresults = nret;
ci->callstatus = mask;
lua_assert(((nresults + 1) & ~CIST_NRESULTS) == 0);
ci->callstatus = mask | cast(l_uint32, nresults + 1);
ci->top.p = top;
return ci;
}
Expand Down Expand Up @@ -664,7 +668,7 @@ l_sinline void ccall (lua_State *L, StkId func, int nResults, l_uint32 inc) {
luaE_checkcstack(L);
}
if ((ci = luaD_precall(L, func, nResults)) != NULL) { /* Lua function? */
ci->callstatus = CIST_FRESH; /* mark that it is a "fresh" execute */
ci->callstatus |= CIST_FRESH; /* mark that it is a "fresh" execute */
luaV_execute(L, ci); /* call it */
}
L->nCcalls -= inc;
Expand Down Expand Up @@ -709,7 +713,7 @@ static int finishpcallk (lua_State *L, CallInfo *ci) {
status = LUA_YIELD; /* was interrupted by an yield */
else { /* error */
StkId func = restorestack(L, ci->u2.funcidx);
L->allowhook = getoah(ci->callstatus); /* restore 'allowhook' */
L->allowhook = getoah(ci); /* restore 'allowhook' */
func = luaF_close(L, func, status, 1); /* can yield or raise an error */
luaD_seterrorobj(L, status, func);
luaD_shrinkstack(L); /* restore stack size in case of overflow */
Expand Down
1 change: 0 additions & 1 deletion lstate.c
Original file line number Diff line number Diff line change
Expand Up @@ -177,7 +177,6 @@ static void stack_init (lua_State *L1, lua_State *L) {
ci->callstatus = CIST_C;
ci->func.p = L1->top.p;
ci->u.c.k = NULL;
ci->nresults = 0;
setnilvalue(s2v(L1->top.p)); /* 'function' entry for this 'ci' */
L1->top.p++;
ci->top.p = L1->top.p + LUA_MINSTACK;
Expand Down
54 changes: 35 additions & 19 deletions lstate.h
Original file line number Diff line number Diff line change
Expand Up @@ -211,31 +211,45 @@ struct CallInfo {
int ntransfer; /* number of values transferred */
} transferinfo;
} u2;
short nresults; /* expected number of results from this function */
unsigned short callstatus;
l_uint32 callstatus;
};


/*
** Bits in CallInfo status
*/
#define CIST_OAH (1<<0) /* original value of 'allowhook' */
#define CIST_C (1<<1) /* call is running a C function */
#define CIST_FRESH (1<<2) /* call is on a fresh "luaV_execute" frame */
#define CIST_HOOKED (1<<3) /* call is running a debug hook */
#define CIST_YPCALL (1<<4) /* doing a yieldable protected call */
#define CIST_TAIL (1<<5) /* call was tail called */
#define CIST_HOOKYIELD (1<<6) /* last hook called yielded */
#define CIST_FIN (1<<7) /* function "called" a finalizer */
#define CIST_TRAN (1<<8) /* 'ci' has transfer information */
#define CIST_CLSRET (1<<9) /* function is closing tbc variables */
/* Bits 10-12 are used for CIST_RECST (see below) */
#define CIST_RECST 10
/* bits 0-7 are the expected number of results from this function + 1 */
#define CIST_NRESULTS 0xff
/* original value of 'allowhook' */
#define CIST_OAH (cast(l_uint32, 1) << 8)
/* call is running a C function */
#define CIST_C (cast(l_uint32, 1) << 9)
/* call is on a fresh "luaV_execute" frame */
#define CIST_FRESH (cast(l_uint32, 1) << 10)
/* call is running a debug hook */
#define CIST_HOOKED (cast(l_uint32, 1) << 11)
/* doing a yieldable protected call */
#define CIST_YPCALL (cast(l_uint32, 1) << 12)
/* call was tail called */
#define CIST_TAIL (cast(l_uint32, 1) << 13)
/* last hook called yielded */
#define CIST_HOOKYIELD (cast(l_uint32, 1) << 14)
/* function "called" a finalizer */
#define CIST_FIN (cast(l_uint32, 1) << 15)
/* 'ci' has transfer information */
#define CIST_TRAN (cast(l_uint32, 1) << 16)
/* function is closing tbc variables */
#define CIST_CLSRET (cast(l_uint32, 1) << 17)
/* Bits 18-20 are used for CIST_RECST (see below) */
#define CIST_RECST 18 /* the offset, not the mask */
#if defined(LUA_COMPAT_LT_LE)
#define CIST_LEQ (1<<13) /* using __lt for __le */
/* using __lt for __le */
#define CIST_LEQ (cast(l_uint32, 1) << 21)
#endif


#define get_nresults(cs) (cast_int((cs) & CIST_NRESULTS) - 1)

/*
** Field CIST_RECST stores the "recover status", used to keep the error
** status while closing to-be-closed variables in coroutines, so that
Expand All @@ -246,7 +260,7 @@ struct CallInfo {
#define setcistrecst(ci,st) \
check_exp(((st) & 7) == (st), /* status must fit in three bits */ \
((ci)->callstatus = ((ci)->callstatus & ~(7 << CIST_RECST)) \
| ((st) << CIST_RECST)))
| (cast(l_uint32, st) << CIST_RECST)))


/* active function is a Lua function */
Expand All @@ -255,9 +269,11 @@ struct CallInfo {
/* call is running Lua code (not a hook) */
#define isLuacode(ci) (!((ci)->callstatus & (CIST_C | CIST_HOOKED)))

/* assume that CIST_OAH has offset 0 and that 'v' is strictly 0/1 */
#define setoah(st,v) ((st) = ((st) & ~CIST_OAH) | (v))
#define getoah(st) ((st) & CIST_OAH)

#define setoah(ci,v) \
((ci)->callstatus = ((v) ? (ci)->callstatus | CIST_OAH \
: (ci)->callstatus & ~CIST_OAH))
#define getoah(ci) (((ci)->callstatus & CIST_OAH) ? 1 : 0)


/*
Expand Down
6 changes: 3 additions & 3 deletions lvm.c
Original file line number Diff line number Diff line change
Expand Up @@ -1742,10 +1742,10 @@ void luaV_execute (lua_State *L, CallInfo *ci) {
trap = 1;
}
else { /* do the 'poscall' here */
int nres;
int nres = get_nresults(ci->callstatus);
L->ci = ci->previous; /* back to caller */
L->top.p = base - 1;
for (nres = ci->nresults; l_unlikely(nres > 0); nres--)
for (; l_unlikely(nres > 0); nres--)
setnilvalue(s2v(L->top.p++)); /* all results are nil */
}
goto ret;
Expand All @@ -1759,7 +1759,7 @@ void luaV_execute (lua_State *L, CallInfo *ci) {
trap = 1;
}
else { /* do the 'poscall' here */
int nres = ci->nresults;
int nres = get_nresults(ci->callstatus);
L->ci = ci->previous; /* back to caller */
if (nres == 0)
L->top.p = base - 1; /* asked for no results */
Expand Down

0 comments on commit 15231d4

Please sign in to comment.