** 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. */
| 406 | ** separated. |
| 407 | */ |
| 408 | static void moveresults (lua_State *L, StkId res, int nres, int wanted) { |
| 409 | StkId firstresult; |
| 410 | int i; |
| 411 | switch (wanted) { /* handle typical cases separately */ |
| 412 | case 0: /* no values needed */ |
| 413 | L->top = res; |
| 414 | return; |
| 415 | case 1: /* one value needed */ |
| 416 | if (nres == 0) /* no results? */ |
| 417 | setnilvalue(s2v(res)); /* adjust with nil */ |
| 418 | else /* at least one result */ |
| 419 | setobjs2s(L, res, L->top - nres); /* move it to proper place */ |
| 420 | L->top = res + 1; |
| 421 | return; |
| 422 | case LUA_MULTRET: |
| 423 | wanted = nres; /* we want all results */ |
| 424 | break; |
| 425 | default: /* two/more results and/or to-be-closed variables */ |
| 426 | if (hastocloseCfunc(wanted)) { /* to-be-closed variables? */ |
| 427 | ptrdiff_t savedres = savestack(L, res); |
| 428 | L->ci->callstatus |= CIST_CLSRET; /* in case of yields */ |
| 429 | L->ci->u2.nres = nres; |
| 430 | luaF_close(L, res, CLOSEKTOP, 1); |
| 431 | L->ci->callstatus &= ~CIST_CLSRET; |
| 432 | if (L->hookmask) /* if needed, call hook after '__close's */ |
| 433 | rethook(L, L->ci, nres); |
| 434 | res = restorestack(L, savedres); /* close and hook can move stack */ |
| 435 | wanted = decodeNresults(wanted); |
| 436 | if (wanted == LUA_MULTRET) |
| 437 | wanted = nres; /* we want all results */ |
| 438 | } |
| 439 | break; |
| 440 | } |
| 441 | /* generic case */ |
| 442 | firstresult = L->top - nres; /* index of first result */ |
| 443 | if (nres > wanted) /* extra results? */ |
| 444 | nres = wanted; /* don't need them */ |
| 445 | for (i = 0; i < nres; i++) /* move all results to correct place */ |
| 446 | setobjs2s(L, res + i, firstresult + i); |
| 447 | for (; i < wanted; i++) /* complete wanted number of results */ |
| 448 | setnilvalue(s2v(res + i)); |
| 449 | L->top = res + wanted; /* top points after the last result */ |
| 450 | } |
| 451 | |
| 452 | |
| 453 | /* |
no test coverage detected