| 263 | |
| 264 | |
| 265 | int luaD_precall (lua_State *L, StkId func, int nresults) { |
| 266 | LClosure *cl; |
| 267 | ptrdiff_t funcr; |
| 268 | if (!ttisfunction(func)) /* `func' is not a function? */ |
| 269 | func = tryfuncTM(L, func); /* check the `function' tag method */ |
| 270 | funcr = savestack(L, func); |
| 271 | cl = &clvalue(func)->l; |
| 272 | L->ci->savedpc = L->savedpc; |
| 273 | if (!cl->isC) { /* Lua function? prepare its call */ |
| 274 | CallInfo *ci; |
| 275 | StkId st, base; |
| 276 | Proto *p = cl->p; |
| 277 | luaD_checkstack(L, p->maxstacksize); |
| 278 | func = restorestack(L, funcr); |
| 279 | |
| 280 | int i, pos = cast_int(func - L->base ) + 2; |
| 281 | for (i = 0; i < p->numparams; ++i) { |
| 282 | if (p->argtypes[i] == 0) continue; |
| 283 | luabb_typeconvert(L, pos + i, p->argtypes[i]); |
| 284 | } |
| 285 | |
| 286 | if (!p->is_vararg) { /* no varargs? */ |
| 287 | base = func + 1; |
| 288 | if (L->top > base + p->numparams) |
| 289 | L->top = base + p->numparams; |
| 290 | } |
| 291 | else { /* vararg function */ |
| 292 | int nargs = cast_int(L->top - func) - 1; |
| 293 | base = adjust_varargs(L, p, nargs); |
| 294 | func = restorestack(L, funcr); /* previous call may change the stack */ |
| 295 | } |
| 296 | ci = inc_ci(L); /* now `enter' new function */ |
| 297 | ci->func = func; |
| 298 | L->base = ci->base = base; |
| 299 | ci->top = L->base + p->maxstacksize; |
| 300 | lua_assert(ci->top <= L->stack_last); |
| 301 | L->savedpc = p->code; /* starting point */ |
| 302 | ci->tailcalls = 0; |
| 303 | ci->nresults = nresults; |
| 304 | for (st = L->top; st < ci->top; st++) |
| 305 | setnilvalue(st); |
| 306 | L->top = ci->top; |
| 307 | if (L->hookmask & LUA_MASKCALL) { |
| 308 | L->savedpc++; /* hooks assume 'pc' is already incremented */ |
| 309 | luaD_callhook(L, LUA_HOOKCALL, -1); |
| 310 | L->savedpc--; /* correct 'pc' */ |
| 311 | } |
| 312 | return PCRLUA; |
| 313 | } |
| 314 | else { /* if is a C function, call it */ |
| 315 | CallInfo *ci; |
| 316 | int n; |
| 317 | luaD_checkstack(L, LUA_MINSTACK); /* ensure minimum stack size */ |
| 318 | ci = inc_ci(L); /* now `enter' new function */ |
| 319 | ci->func = restorestack(L, funcr); |
| 320 | L->base = ci->base = ci->func + 1; |
| 321 | ci->top = L->top + LUA_MINSTACK; |
| 322 | lua_assert(ci->top <= L->stack_last); |
no test coverage detected