** Prepares a function call: checks the stack, creates a new CallInfo ** entry, fills in the relevant information, calls hook if needed. ** If function is a C function, does the call, too. (Otherwise, leave ** the execution ('luaV_execute') to the caller, to allow stackless ** calls.) Returns true iff function has been executed (C function). */
| 411 | ** calls.) Returns true iff function has been executed (C function). |
| 412 | */ |
| 413 | int luaD_precall (lua_State *L, StkId func, int nresults) { |
| 414 | lua_CFunction f; |
| 415 | CallInfo *ci; |
| 416 | switch (ttype(func)) { |
| 417 | case LUA_TCCL: /* C closure */ |
| 418 | f = clCvalue(func)->f; |
| 419 | goto Cfunc; |
| 420 | case LUA_TLCF: /* light C function */ |
| 421 | f = fvalue(func); |
| 422 | Cfunc: { |
| 423 | int n; /* number of returns */ |
| 424 | checkstackp(L, LUA_MINSTACK, func); /* ensure minimum stack size */ |
| 425 | ci = next_ci(L); /* now 'enter' new function */ |
| 426 | ci->nresults = nresults; |
| 427 | ci->func = func; |
| 428 | ci->top = L->top + LUA_MINSTACK; |
| 429 | lua_assert(ci->top <= L->stack_last); |
| 430 | ci->callstatus = 0; |
| 431 | if (L->hookmask & LUA_MASKCALL) |
| 432 | luaD_hook(L, LUA_HOOKCALL, -1); |
| 433 | lua_unlock(L); |
| 434 | n = (*f)(L); /* do the actual call */ |
| 435 | lua_lock(L); |
| 436 | api_checknelems(L, n); |
| 437 | luaD_poscall(L, ci, L->top - n, n); |
| 438 | return 1; |
| 439 | } |
| 440 | case LUA_TLCL: { /* Lua function: prepare its call */ |
| 441 | StkId base; |
| 442 | Proto *p = clLvalue(func)->p; |
| 443 | int n = cast_int(L->top - func) - 1; /* number of real arguments */ |
| 444 | int fsize = p->maxstacksize; /* frame size */ |
| 445 | checkstackp(L, fsize, func); |
| 446 | if (p->is_vararg) |
| 447 | base = adjust_varargs(L, p, n); |
| 448 | else { /* non vararg function */ |
| 449 | for (; n < p->numparams; n++) |
| 450 | setnilvalue(L->top++); /* complete missing arguments */ |
| 451 | base = func + 1; |
| 452 | } |
| 453 | ci = next_ci(L); /* now 'enter' new function */ |
| 454 | ci->nresults = nresults; |
| 455 | ci->func = func; |
| 456 | ci->u.l.base = base; |
| 457 | L->top = ci->top = base + fsize; |
| 458 | lua_assert(ci->top <= L->stack_last); |
| 459 | ci->u.l.savedpc = p->code; /* starting point */ |
| 460 | ci->callstatus = CIST_LUA; |
| 461 | if (L->hookmask & LUA_MASKCALL) |
| 462 | callhook(L, ci); |
| 463 | return 0; |
| 464 | } |
| 465 | default: { /* not a function */ |
| 466 | checkstackp(L, 1, func); /* ensure space for metamethod */ |
| 467 | tryfuncTM(L, func); /* try to get '__call' metamethod */ |
| 468 | return luaD_precall(L, func, nresults); /* now it must be a function */ |
| 469 | } |
| 470 | } |
no test coverage detected