diff options
author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2025-01-28 11:45:45 -0300 |
---|---|---|
committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2025-01-28 11:45:45 -0300 |
commit | 39a14ea7d7b14172595c61619e8f35c2614b2606 (patch) | |
tree | 863ea56e6014de9e1284f2e47ac1fbd4b69339ed /ldo.c | |
parent | c4e7cdb541d89142056927ebdfd8f97017d38f45 (diff) | |
download | lua-39a14ea7d7b14172595c61619e8f35c2614b2606.tar.gz lua-39a14ea7d7b14172595c61619e8f35c2614b2606.tar.bz2 lua-39a14ea7d7b14172595c61619e8f35c2614b2606.zip |
CallInfo bit CIST_CLSRET broken in two
Since commit f407b3c4a, it was being used for two distinct (and
incompatible) meanings:
A: Function has TBC variables (now bit CIST_TBC)
B: Interpreter is closing TBC variables (original bit CIST_CLSRET)
B implies A, but A does not imply B.
Diffstat (limited to 'ldo.c')
-rw-r--r-- | ldo.c | 12 |
1 files changed, 7 insertions, 5 deletions
@@ -505,7 +505,7 @@ l_sinline void genmoveresults (lua_State *L, StkId res, int nres, | |||
505 | ** Given 'nres' results at 'firstResult', move 'fwanted-1' of them | 505 | ** Given 'nres' results at 'firstResult', move 'fwanted-1' of them |
506 | ** to 'res'. Handle most typical cases (zero results for commands, | 506 | ** to 'res'. Handle most typical cases (zero results for commands, |
507 | ** one result for expressions, multiple results for tail calls/single | 507 | ** one result for expressions, multiple results for tail calls/single |
508 | ** parameters) separated. The flag CIST_CLSRET in 'fwanted', if set, | 508 | ** parameters) separated. The flag CIST_TBC in 'fwanted', if set, |
509 | ** forces the swicth to go to the default case. | 509 | ** forces the swicth to go to the default case. |
510 | */ | 510 | */ |
511 | l_sinline void moveresults (lua_State *L, StkId res, int nres, | 511 | l_sinline void moveresults (lua_State *L, StkId res, int nres, |
@@ -526,8 +526,9 @@ l_sinline void moveresults (lua_State *L, StkId res, int nres, | |||
526 | break; | 526 | break; |
527 | default: { /* two/more results and/or to-be-closed variables */ | 527 | default: { /* two/more results and/or to-be-closed variables */ |
528 | int wanted = get_nresults(fwanted); | 528 | int wanted = get_nresults(fwanted); |
529 | if (fwanted & CIST_CLSRET) { /* to-be-closed variables? */ | 529 | if (fwanted & CIST_TBC) { /* to-be-closed variables? */ |
530 | L->ci->u2.nres = nres; | 530 | L->ci->u2.nres = nres; |
531 | L->ci->callstatus |= CIST_CLSRET; /* in case of yields */ | ||
531 | res = luaF_close(L, res, CLOSEKTOP, 1); | 532 | res = luaF_close(L, res, CLOSEKTOP, 1); |
532 | L->ci->callstatus &= ~CIST_CLSRET; | 533 | L->ci->callstatus &= ~CIST_CLSRET; |
533 | if (L->hookmask) { /* if needed, call hook after '__close's */ | 534 | if (L->hookmask) { /* if needed, call hook after '__close's */ |
@@ -552,8 +553,8 @@ l_sinline void moveresults (lua_State *L, StkId res, int nres, | |||
552 | ** that. | 553 | ** that. |
553 | */ | 554 | */ |
554 | void luaD_poscall (lua_State *L, CallInfo *ci, int nres) { | 555 | void luaD_poscall (lua_State *L, CallInfo *ci, int nres) { |
555 | l_uint32 fwanted = ci->callstatus & (CIST_CLSRET | CIST_NRESULTS); | 556 | l_uint32 fwanted = ci->callstatus & (CIST_TBC | CIST_NRESULTS); |
556 | if (l_unlikely(L->hookmask) && !(fwanted & CIST_CLSRET)) | 557 | if (l_unlikely(L->hookmask) && !(fwanted & CIST_TBC)) |
557 | rethook(L, ci, nres); | 558 | rethook(L, ci, nres); |
558 | /* move results to proper place */ | 559 | /* move results to proper place */ |
559 | moveresults(L, ci->func.p, nres, fwanted); | 560 | moveresults(L, ci->func.p, nres, fwanted); |
@@ -785,7 +786,8 @@ static int finishpcallk (lua_State *L, CallInfo *ci) { | |||
785 | */ | 786 | */ |
786 | static void finishCcall (lua_State *L, CallInfo *ci) { | 787 | static void finishCcall (lua_State *L, CallInfo *ci) { |
787 | int n; /* actual number of results from C function */ | 788 | int n; /* actual number of results from C function */ |
788 | if (ci->callstatus & CIST_CLSRET) { /* was returning? */ | 789 | if (ci->callstatus & CIST_CLSRET) { /* was closing TBC variable? */ |
790 | lua_assert(ci->callstatus & CIST_TBC); | ||
789 | n = ci->u2.nres; /* just redo 'luaD_poscall' */ | 791 | n = ci->u2.nres; /* just redo 'luaD_poscall' */ |
790 | /* don't need to reset CIST_CLSRET, as it will be set again anyway */ | 792 | /* don't need to reset CIST_CLSRET, as it will be set again anyway */ |
791 | } | 793 | } |