diff options
Diffstat (limited to 'src/lj_dispatch.c')
-rw-r--r-- | src/lj_dispatch.c | 26 |
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. */ |
388 | static void call_init(lua_State *L, GCfunc *fn) | 388 | static 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 |
426 | out: | 434 | out: |
427 | #endif | 435 | #endif |