@@ -452,16 +452,31 @@ static StkId tryfuncTM (lua_State *L, StkId func) {
452
452
}
453
453
454
454
455
+ /* Generic case for 'moveresult */
456
+ l_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'.
457
- ** Handle most typical cases (zero results for commands, one result for
458
- ** expressions, multiple results for tail calls/single parameters)
459
- ** separated.
471
+ ** Given 'nres' results at 'firstResult', move 'fwanted-1' of them
472
+ ** to 'res'. Handle most typical cases (zero results for commands,
473
+ ** one result for expressions, multiple results for tail calls/single
474
+ ** parameters) separated. The flag CIST_CLSRET in 'fwanted', if set,
475
+ ** forces the swicth to go to the default case.
460
476
*/
461
- l_sinline void moveresults (lua_State * L , StkId res , int nres , int wanted ) {
462
- StkId firstresult ;
463
- int i ;
464
- switch (wanted ) { /* handle typical cases separately */
477
+ l_sinline void moveresults (lua_State * L , StkId res , int nres ,
478
+ l_uint32 fwanted ) {
479
+ switch (fwanted ) { /* handle typical cases separately */
465
480
case 0 + 1 : /* no values needed */
466
481
L -> top .p = res ;
467
482
return ;
@@ -473,12 +488,11 @@ l_sinline void moveresults (lua_State *L, StkId res, int nres, int wanted) {
473
488
L -> top .p = res + 1 ;
474
489
return ;
475
490
case LUA_MULTRET + 1 :
476
- wanted = nres ; /* we want all results */
491
+ genmoveresults ( L , res , nres , nres ) ; /* we want all results */
477
492
break ;
478
- default : /* two/more results and/or to-be-closed variables */
479
- if (!(wanted & CIST_CLSRET ))
480
- wanted -- ;
481
- else { /* to-be-closed variables? */
493
+ default : { /* two/more results and/or to-be-closed variables */
494
+ int wanted = get_nresults (fwanted );
495
+ if (fwanted & CIST_CLSRET ) { /* to-be-closed variables? */
482
496
L -> ci -> u2 .nres = nres ;
483
497
res = luaF_close (L , res , CLOSEKTOP , 1 );
484
498
L -> ci -> callstatus &= ~CIST_CLSRET ;
@@ -487,21 +501,13 @@ l_sinline void moveresults (lua_State *L, StkId res, int nres, int wanted) {
487
501
rethook (L , L -> ci , nres );
488
502
res = restorestack (L , savedres ); /* hook can move stack */
489
503
}
490
- wanted = (wanted & ~CIST_CLSRET ) - 1 ;
491
504
if (wanted == LUA_MULTRET )
492
505
wanted = nres ; /* we want all results */
493
506
}
507
+ genmoveresults (L , res , nres , wanted );
494
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
518
** that.
513
519
*/
514
520
void luaD_poscall (lua_State * L , CallInfo * ci , int nres ) {
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 ))
521
+ l_uint32 fwanted = ci -> callstatus & (CIST_CLSRET | CIST_NRESULTS );
522
+ if (l_unlikely (L -> hookmask ) && !(fwanted & CIST_CLSRET ))
519
523
rethook (L , ci , nres );
520
524
/* move results to proper place */
521
- moveresults (L , ci -> func .p , nres , wanted );
525
+ moveresults (L , ci -> func .p , nres , fwanted );
522
526
/* function cannot be in any of these cases when returning */
523
527
lua_assert (!(ci -> callstatus &
524
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
534
#define next_ci (L ) (L->ci->next ? L->ci->next : luaE_extendCI(L))
531
535
532
536
533
- l_sinline CallInfo * prepCallInfo (lua_State * L , StkId func , int nret ,
534
- int mask , StkId top ) {
537
+ l_sinline CallInfo * prepCallInfo (lua_State * L , StkId func , int nresults ,
538
+ l_uint32 mask , StkId top ) {
535
539
CallInfo * ci = L -> ci = next_ci (L ); /* new frame */
536
540
ci -> func .p = func ;
537
- ci -> nresults = nret ;
538
- ci -> callstatus = mask ;
541
+ lua_assert ((( nresults + 1 ) & ~ CIST_NRESULTS ) == 0 ) ;
542
+ ci -> callstatus = mask | cast ( l_uint32 , nresults + 1 ) ;
539
543
ci -> top .p = top ;
540
544
return ci ;
541
545
}
@@ -664,7 +668,7 @@ l_sinline void ccall (lua_State *L, StkId func, int nResults, l_uint32 inc) {
664
668
luaE_checkcstack (L );
665
669
}
666
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
672
luaV_execute (L , ci ); /* call it */
669
673
}
670
674
L -> nCcalls -= inc ;
@@ -709,7 +713,7 @@ static int finishpcallk (lua_State *L, CallInfo *ci) {
709
713
status = LUA_YIELD ; /* was interrupted by an yield */
710
714
else { /* error */
711
715
StkId func = restorestack (L , ci -> u2 .funcidx );
712
- L -> allowhook = getoah (ci -> callstatus ); /* restore 'allowhook' */
716
+ L -> allowhook = getoah (ci ); /* restore 'allowhook' */
713
717
func = luaF_close (L , func , status , 1 ); /* can yield or raise an error */
714
718
luaD_seterrorobj (L , status , func );
715
719
luaD_shrinkstack (L ); /* restore stack size in case of overflow */
0 commit comments