aboutsummaryrefslogtreecommitdiff
path: root/ldo.c
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>2024-07-21 14:56:59 -0300
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>2024-07-21 14:56:59 -0300
commit15231d4fb2f6984b25e0353ff46eda1a180b686d (patch)
treefea343d493f04539a2a9ebe46c838cc5b8a01cd5 /ldo.c
parentf407b3c4a1bc9667867ec51e835c20d97aab55a2 (diff)
downloadlua-15231d4fb2f6984b25e0353ff46eda1a180b686d.tar.gz
lua-15231d4fb2f6984b25e0353ff46eda1a180b686d.tar.bz2
lua-15231d4fb2f6984b25e0353ff46eda1a180b686d.zip
'nresults' moved into 'callstatus'
That gives us more free bits in 'callstatus', for future use.
Diffstat (limited to 'ldo.c')
-rw-r--r--ldo.c72
1 files changed, 38 insertions, 34 deletions
diff --git a/ldo.c b/ldo.c
index 6eaa31a0..933a55bf 100644
--- a/ldo.c
+++ b/ldo.c
@@ -452,16 +452,31 @@ static StkId tryfuncTM (lua_State *L, StkId func) {
452} 452}
453 453
454 454
455/* Generic case for 'moveresult */
456l_sinline void genmoveresults (lua_State *L, StkId res, int nres,
457 int wanted) {
458 StkId firstresult = L->top.p - nres; /* index of first result */
459 int i;
460 if (nres > wanted) /* extra results? */
461 nres = wanted; /* don't need them */
462 for (i = 0; i < nres; i++) /* move all results to correct place */
463 setobjs2s(L, res + i, firstresult + i);
464 for (; i < wanted; i++) /* complete wanted number of results */
465 setnilvalue(s2v(res + i));
466 L->top.p = res + wanted; /* top points after the last result */
467}
468
469
455/* 470/*
456** Given 'nres' results at 'firstResult', move 'wanted' of them to 'res'. 471** Given 'nres' results at 'firstResult', move 'fwanted-1' of them
457** Handle most typical cases (zero results for commands, one result for 472** to 'res'. Handle most typical cases (zero results for commands,
458** expressions, multiple results for tail calls/single parameters) 473** one result for expressions, multiple results for tail calls/single
459** separated. 474** parameters) separated. The flag CIST_CLSRET in 'fwanted', if set,
475** forces the swicth to go to the default case.
460*/ 476*/
461l_sinline void moveresults (lua_State *L, StkId res, int nres, int wanted) { 477l_sinline void moveresults (lua_State *L, StkId res, int nres,
462 StkId firstresult; 478 l_uint32 fwanted) {
463 int i; 479 switch (fwanted) { /* handle typical cases separately */
464 switch (wanted) { /* handle typical cases separately */
465 case 0 + 1: /* no values needed */ 480 case 0 + 1: /* no values needed */
466 L->top.p = res; 481 L->top.p = res;
467 return; 482 return;
@@ -473,12 +488,11 @@ l_sinline void moveresults (lua_State *L, StkId res, int nres, int wanted) {
473 L->top.p = res + 1; 488 L->top.p = res + 1;
474 return; 489 return;
475 case LUA_MULTRET + 1: 490 case LUA_MULTRET + 1:
476 wanted = nres; /* we want all results */ 491 genmoveresults(L, res, nres, nres); /* we want all results */
477 break; 492 break;
478 default: /* two/more results and/or to-be-closed variables */ 493 default: { /* two/more results and/or to-be-closed variables */
479 if (!(wanted & CIST_CLSRET)) 494 int wanted = get_nresults(fwanted);
480 wanted--; 495 if (fwanted & CIST_CLSRET) { /* to-be-closed variables? */
481 else { /* to-be-closed variables? */
482 L->ci->u2.nres = nres; 496 L->ci->u2.nres = nres;
483 res = luaF_close(L, res, CLOSEKTOP, 1); 497 res = luaF_close(L, res, CLOSEKTOP, 1);
484 L->ci->callstatus &= ~CIST_CLSRET; 498 L->ci->callstatus &= ~CIST_CLSRET;
@@ -487,21 +501,13 @@ l_sinline void moveresults (lua_State *L, StkId res, int nres, int wanted) {
487 rethook(L, L->ci, nres); 501 rethook(L, L->ci, nres);
488 res = restorestack(L, savedres); /* hook can move stack */ 502 res = restorestack(L, savedres); /* hook can move stack */
489 } 503 }
490 wanted = (wanted & ~CIST_CLSRET) - 1;
491 if (wanted == LUA_MULTRET) 504 if (wanted == LUA_MULTRET)
492 wanted = nres; /* we want all results */ 505 wanted = nres; /* we want all results */
493 } 506 }
507 genmoveresults(L, res, nres, wanted);
494 break; 508 break;
509 }
495 } 510 }
496 /* generic case */
497 firstresult = L->top.p - nres; /* index of first result */
498 if (nres > wanted) /* extra results? */
499 nres = wanted; /* don't need them */
500 for (i = 0; i < nres; i++) /* move all results to correct place */
501 setobjs2s(L, res + i, firstresult + i);
502 for (; i < wanted; i++) /* complete wanted number of results */
503 setnilvalue(s2v(res + i));
504 L->top.p = res + wanted; /* top points after the last result */
505} 511}
506 512
507 513
@@ -512,13 +518,11 @@ l_sinline void moveresults (lua_State *L, StkId res, int nres, int wanted) {
512** that. 518** that.
513*/ 519*/
514void luaD_poscall (lua_State *L, CallInfo *ci, int nres) { 520void luaD_poscall (lua_State *L, CallInfo *ci, int nres) {
515 int wanted = ci->nresults + 1; 521 l_uint32 fwanted = ci->callstatus & (CIST_CLSRET | CIST_NRESULTS);
516 if (ci->callstatus & CIST_CLSRET) 522 if (l_unlikely(L->hookmask) && !(fwanted & CIST_CLSRET))
517 wanted |= CIST_CLSRET; /* don't check hook in this case */
518 else if (l_unlikely(L->hookmask))
519 rethook(L, ci, nres); 523 rethook(L, ci, nres);
520 /* move results to proper place */ 524 /* move results to proper place */
521 moveresults(L, ci->func.p, nres, wanted); 525 moveresults(L, ci->func.p, nres, fwanted);
522 /* function cannot be in any of these cases when returning */ 526 /* function cannot be in any of these cases when returning */
523 lua_assert(!(ci->callstatus & 527 lua_assert(!(ci->callstatus &
524 (CIST_HOOKED | CIST_YPCALL | CIST_FIN | CIST_TRAN | CIST_CLSRET))); 528 (CIST_HOOKED | CIST_YPCALL | CIST_FIN | CIST_TRAN | CIST_CLSRET)));
@@ -530,12 +534,12 @@ void luaD_poscall (lua_State *L, CallInfo *ci, int nres) {
530#define next_ci(L) (L->ci->next ? L->ci->next : luaE_extendCI(L)) 534#define next_ci(L) (L->ci->next ? L->ci->next : luaE_extendCI(L))
531 535
532 536
533l_sinline CallInfo *prepCallInfo (lua_State *L, StkId func, int nret, 537l_sinline CallInfo *prepCallInfo (lua_State *L, StkId func, int nresults,
534 int mask, StkId top) { 538 l_uint32 mask, StkId top) {
535 CallInfo *ci = L->ci = next_ci(L); /* new frame */ 539 CallInfo *ci = L->ci = next_ci(L); /* new frame */
536 ci->func.p = func; 540 ci->func.p = func;
537 ci->nresults = nret; 541 lua_assert(((nresults + 1) & ~CIST_NRESULTS) == 0);
538 ci->callstatus = mask; 542 ci->callstatus = mask | cast(l_uint32, nresults + 1);
539 ci->top.p = top; 543 ci->top.p = top;
540 return ci; 544 return ci;
541} 545}
@@ -664,7 +668,7 @@ l_sinline void ccall (lua_State *L, StkId func, int nResults, l_uint32 inc) {
664 luaE_checkcstack(L); 668 luaE_checkcstack(L);
665 } 669 }
666 if ((ci = luaD_precall(L, func, nResults)) != NULL) { /* Lua function? */ 670 if ((ci = luaD_precall(L, func, nResults)) != NULL) { /* Lua function? */
667 ci->callstatus = CIST_FRESH; /* mark that it is a "fresh" execute */ 671 ci->callstatus |= CIST_FRESH; /* mark that it is a "fresh" execute */
668 luaV_execute(L, ci); /* call it */ 672 luaV_execute(L, ci); /* call it */
669 } 673 }
670 L->nCcalls -= inc; 674 L->nCcalls -= inc;
@@ -709,7 +713,7 @@ static int finishpcallk (lua_State *L, CallInfo *ci) {
709 status = LUA_YIELD; /* was interrupted by an yield */ 713 status = LUA_YIELD; /* was interrupted by an yield */
710 else { /* error */ 714 else { /* error */
711 StkId func = restorestack(L, ci->u2.funcidx); 715 StkId func = restorestack(L, ci->u2.funcidx);
712 L->allowhook = getoah(ci->callstatus); /* restore 'allowhook' */ 716 L->allowhook = getoah(ci); /* restore 'allowhook' */
713 func = luaF_close(L, func, status, 1); /* can yield or raise an error */ 717 func = luaF_close(L, func, status, 1); /* can yield or raise an error */
714 luaD_seterrorobj(L, status, func); 718 luaD_seterrorobj(L, status, func);
715 luaD_shrinkstack(L); /* restore stack size in case of overflow */ 719 luaD_shrinkstack(L); /* restore stack size in case of overflow */