Skip to content

Commit f407b3c

Browse files
committed
Using CIST_CLSRET instead of trick with 'nresults'
The callstatus flag CIST_CLSRET is used in all tests for the presence of variables to be closed in C functions.
1 parent a546138 commit f407b3c

File tree

4 files changed

+31
-30
lines changed

4 files changed

+31
-30
lines changed

lapi.c

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -207,7 +207,7 @@ LUA_API void lua_settop (lua_State *L, int idx) {
207207
}
208208
newtop = L->top.p + diff;
209209
if (diff < 0 && L->tbclist.p >= newtop) {
210-
lua_assert(hastocloseCfunc(ci->nresults));
210+
lua_assert(ci->callstatus & CIST_CLSRET);
211211
newtop = luaF_close(L, newtop, CLOSEKTOP, 0);
212212
}
213213
L->top.p = newtop; /* correct top only after closing any upvalue */
@@ -219,7 +219,7 @@ LUA_API void lua_closeslot (lua_State *L, int idx) {
219219
StkId level;
220220
lua_lock(L);
221221
level = index2stack(L, idx);
222-
api_check(L, hastocloseCfunc(L->ci->nresults) && L->tbclist.p == level,
222+
api_check(L, (L->ci->callstatus & CIST_CLSRET) && L->tbclist.p == level,
223223
"no variable to close at given level");
224224
level = luaF_close(L, level, CLOSEKTOP, 0);
225225
setnilvalue(s2v(level));
@@ -1287,9 +1287,7 @@ LUA_API void lua_toclose (lua_State *L, int idx) {
12871287
nresults = L->ci->nresults;
12881288
api_check(L, L->tbclist.p < o, "given index below or equal a marked one");
12891289
luaF_newtbcupval(L, o); /* create new to-be-closed upvalue */
1290-
if (!hastocloseCfunc(nresults)) /* function not marked yet? */
1291-
L->ci->nresults = codeNresults(nresults); /* mark it */
1292-
lua_assert(hastocloseCfunc(L->ci->nresults));
1290+
L->ci->callstatus |= CIST_CLSRET; /* mark that function has TBC slots */
12931291
lua_unlock(L);
12941292
}
12951293

lapi.h

Lines changed: 0 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -62,20 +62,4 @@
6262
L->tbclist.p < L->top.p - (n), \
6363
"not enough free elements in the stack")
6464

65-
66-
/*
67-
** To reduce the overhead of returning from C functions, the presence of
68-
** to-be-closed variables in these functions is coded in the CallInfo's
69-
** field 'nresults', in a way that functions with no to-be-closed variables
70-
** with zero, one, or "all" wanted results have no overhead. Functions
71-
** with other number of wanted results, as well as functions with
72-
** variables to be closed, have an extra check.
73-
*/
74-
75-
#define hastocloseCfunc(n) ((n) < LUA_MULTRET)
76-
77-
/* Map [-1, inf) (range of 'nresults') into (-inf, -2] */
78-
#define codeNresults(n) (-(n) - 3)
79-
#define decodeNresults(n) (-(n) - 3)
80-
8165
#endif

ldo.c

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -462,22 +462,23 @@ l_sinline void moveresults (lua_State *L, StkId res, int nres, int wanted) {
462462
StkId firstresult;
463463
int i;
464464
switch (wanted) { /* handle typical cases separately */
465-
case 0: /* no values needed */
465+
case 0 + 1: /* no values needed */
466466
L->top.p = res;
467467
return;
468-
case 1: /* one value needed */
468+
case 1 + 1: /* one value needed */
469469
if (nres == 0) /* no results? */
470470
setnilvalue(s2v(res)); /* adjust with nil */
471471
else /* at least one result */
472472
setobjs2s(L, res, L->top.p - nres); /* move it to proper place */
473473
L->top.p = res + 1;
474474
return;
475-
case LUA_MULTRET:
475+
case LUA_MULTRET + 1:
476476
wanted = nres; /* we want all results */
477477
break;
478478
default: /* two/more results and/or to-be-closed variables */
479-
if (hastocloseCfunc(wanted)) { /* to-be-closed variables? */
480-
L->ci->callstatus |= CIST_CLSRET; /* in case of yields */
479+
if (!(wanted & CIST_CLSRET))
480+
wanted--;
481+
else { /* to-be-closed variables? */
481482
L->ci->u2.nres = nres;
482483
res = luaF_close(L, res, CLOSEKTOP, 1);
483484
L->ci->callstatus &= ~CIST_CLSRET;
@@ -486,7 +487,7 @@ l_sinline void moveresults (lua_State *L, StkId res, int nres, int wanted) {
486487
rethook(L, L->ci, nres);
487488
res = restorestack(L, savedres); /* hook can move stack */
488489
}
489-
wanted = decodeNresults(wanted);
490+
wanted = (wanted & ~CIST_CLSRET) - 1;
490491
if (wanted == LUA_MULTRET)
491492
wanted = nres; /* we want all results */
492493
}
@@ -511,8 +512,10 @@ l_sinline void moveresults (lua_State *L, StkId res, int nres, int wanted) {
511512
** that.
512513
*/
513514
void luaD_poscall (lua_State *L, CallInfo *ci, int nres) {
514-
int wanted = ci->nresults;
515-
if (l_unlikely(L->hookmask && !hastocloseCfunc(wanted)))
515+
int wanted = ci->nresults + 1;
516+
if (ci->callstatus & CIST_CLSRET)
517+
wanted |= CIST_CLSRET; /* don't check hook in this case */
518+
else if (l_unlikely(L->hookmask))
516519
rethook(L, ci, nres);
517520
/* move results to proper place */
518521
moveresults(L, ci->func.p, nres, wanted);
@@ -736,7 +739,6 @@ static int finishpcallk (lua_State *L, CallInfo *ci) {
736739
static void finishCcall (lua_State *L, CallInfo *ci) {
737740
int n; /* actual number of results from C function */
738741
if (ci->callstatus & CIST_CLSRET) { /* was returning? */
739-
lua_assert(hastocloseCfunc(ci->nresults));
740742
n = ci->u2.nres; /* just redo 'luaD_poscall' */
741743
/* don't need to reset CIST_CLSRET, as it will be set again anyway */
742744
}

testes/api.lua

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,23 @@ do -- test returning more results than fit in the caller stack
165165
end
166166

167167

168+
do -- testing multipe returns
169+
local function foo (n)
170+
if n > 0 then return n, foo(n - 1) end
171+
end
172+
173+
local t = {T.testC("call 1 10; return 10", foo, 20)}
174+
assert(t[1] == 20 and t[10] == 11 and t[11] == nil)
175+
176+
local t = table.pack(T.testC("call 1 10; return 10", foo, 2))
177+
assert(t[1] == 2 and t[2] == 1 and t[3] == nil and t.n == 10)
178+
179+
local t = {T.testC([[
180+
checkstack 300 "error"; call 1 250; return 250]], foo, 250)}
181+
assert(t[1] == 250 and t[250] == 1 and t[251] == nil)
182+
end
183+
184+
168185
-- testing globals
169186
_G.AA = 14; _G.BB = "a31"
170187
local a = {T.testC[[

0 commit comments

Comments
 (0)