** Prepares the call to a function (C or Lua). For C functions, also do ** the call. The function to be called is at '*func'. The arguments ** are on the stack, right after the function. Returns the CallInfo ** to be executed, if it was a Lua function. Otherwise (a C function) ** returns NULL, with all the results on the stack, starting at the ** original function position. */
| 506 | ** original function position. |
| 507 | */ |
| 508 | CallInfo *luaD_precall (lua_State *L, StkId func, int nresults) { |
| 509 | lua_CFunction f; |
| 510 | retry: |
| 511 | switch (ttypetag(s2v(func))) { |
| 512 | case LUA_VCCL: /* C closure */ |
| 513 | f = clCvalue(s2v(func))->f; |
| 514 | goto Cfunc; |
| 515 | case LUA_VLCF: /* light C function */ |
| 516 | f = fvalue(s2v(func)); |
| 517 | Cfunc: { |
| 518 | int n; /* number of returns */ |
| 519 | CallInfo *ci; |
| 520 | checkstackGCp(L, LUA_MINSTACK, func); /* ensure minimum stack size */ |
| 521 | L->ci = ci = next_ci(L); |
| 522 | ci->nresults = nresults; |
| 523 | ci->callstatus = CIST_C; |
| 524 | ci->top = L->top + LUA_MINSTACK; |
| 525 | ci->func = func; |
| 526 | lua_assert(ci->top <= L->stack_last); |
| 527 | if (l_unlikely(L->hookmask & LUA_MASKCALL)) { |
| 528 | int narg = cast_int(L->top - func) - 1; |
| 529 | luaD_hook(L, LUA_HOOKCALL, -1, 1, narg); |
| 530 | } |
| 531 | lua_unlock(L); |
| 532 | n = (*f)(L); /* do the actual call */ |
| 533 | lua_lock(L); |
| 534 | api_checknelems(L, n); |
| 535 | luaD_poscall(L, ci, n); |
| 536 | return NULL; |
| 537 | } |
| 538 | case LUA_VLCL: { /* Lua function */ |
| 539 | CallInfo *ci; |
| 540 | Proto *p = clLvalue(s2v(func))->p; |
| 541 | int narg = cast_int(L->top - func) - 1; /* number of real arguments */ |
| 542 | int nfixparams = p->numparams; |
| 543 | int fsize = p->maxstacksize; /* frame size */ |
| 544 | checkstackGCp(L, fsize, func); |
| 545 | L->ci = ci = next_ci(L); |
| 546 | ci->nresults = nresults; |
| 547 | ci->u.l.savedpc = p->code; /* starting point */ |
| 548 | ci->top = func + 1 + fsize; |
| 549 | ci->func = func; |
| 550 | L->ci = ci; |
| 551 | for (; narg < nfixparams; narg++) |
| 552 | setnilvalue(s2v(L->top++)); /* complete missing arguments */ |
| 553 | lua_assert(ci->top <= L->stack_last); |
| 554 | return ci; |
| 555 | } |
| 556 | default: { /* not a function */ |
| 557 | checkstackGCp(L, 1, func); /* space for metamethod */ |
| 558 | luaD_tryfuncTM(L, func); /* try to get '__call' metamethod */ |
| 559 | goto retry; /* try again with metamethod */ |
| 560 | } |
| 561 | } |
| 562 | } |
| 563 | |
| 564 | |
| 565 | /* |
no test coverage detected