aboutsummaryrefslogtreecommitdiff
path: root/src/lj_dispatch.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/lj_dispatch.c')
-rw-r--r--src/lj_dispatch.c26
1 files changed, 17 insertions, 9 deletions
diff --git a/src/lj_dispatch.c b/src/lj_dispatch.c
index 491c5aa3..3b1be7e2 100644
--- a/src/lj_dispatch.c
+++ b/src/lj_dispatch.c
@@ -384,17 +384,18 @@ void LJ_FASTCALL lj_dispatch_ins(lua_State *L, const BCIns *pc)
384 callhook(L, LUA_HOOKRET, -1); 384 callhook(L, LUA_HOOKRET, -1);
385} 385}
386 386
387/* Initialize call. Ensure stack space and clear missing parameters. */ 387/* Initialize call. Ensure stack space and return # of missing parameters. */
388static void call_init(lua_State *L, GCfunc *fn) 388static int call_init(lua_State *L, GCfunc *fn)
389{ 389{
390 if (isluafunc(fn)) { 390 if (isluafunc(fn)) {
391 MSize numparams = funcproto(fn)->numparams; 391 int numparams = funcproto(fn)->numparams;
392 TValue *o; 392 int gotparams = (int)(L->top - L->base);
393 lj_state_checkstack(L, numparams); 393 lj_state_checkstack(L, (MSize)numparams);
394 for (o = L->base + numparams; L->top < o; L->top++) 394 numparams -= gotparams;
395 setnilV(L->top); /* Clear missing parameters. */ 395 return numparams >= 0 ? numparams : 0;
396 } else { 396 } else {
397 lj_state_checkstack(L, LUA_MINSTACK); 397 lj_state_checkstack(L, LUA_MINSTACK);
398 return 0;
398 } 399 }
399} 400}
400 401
@@ -407,7 +408,7 @@ ASMFunction LJ_FASTCALL lj_dispatch_call(lua_State *L, const BCIns *pc)
407#if LJ_HASJIT 408#if LJ_HASJIT
408 jit_State *J = G2J(g); 409 jit_State *J = G2J(g);
409#endif 410#endif
410 call_init(L, fn); 411 int missing = call_init(L, fn);
411#if LJ_HASJIT 412#if LJ_HASJIT
412 J->L = L; 413 J->L = L;
413 if ((uintptr_t)pc & 1) { /* Marker for hot call. */ 414 if ((uintptr_t)pc & 1) { /* Marker for hot call. */
@@ -420,8 +421,15 @@ ASMFunction LJ_FASTCALL lj_dispatch_call(lua_State *L, const BCIns *pc)
420 lj_trace_ins(J, pc-1); /* The interpreter bytecode PC is offset by 1. */ 421 lj_trace_ins(J, pc-1); /* The interpreter bytecode PC is offset by 1. */
421 } 422 }
422#endif 423#endif
423 if ((g->hookmask & LUA_MASKCALL)) 424 if ((g->hookmask & LUA_MASKCALL)) {
425 int i;
426 for (i = 0; i < missing; i++) /* Add missing parameters. */
427 setnilV(L->top++);
424 callhook(L, LUA_HOOKCALL, -1); 428 callhook(L, LUA_HOOKCALL, -1);
429 /* Preserve modifications of missing parameters by lua_setlocal(). */
430 while (missing-- > 0 && tvisnil(L->top - 1))
431 L->top--;
432 }
425#if LJ_HASJIT 433#if LJ_HASJIT
426out: 434out:
427#endif 435#endif