diff options
| -rw-r--r-- | src/lj_dispatch.c | 26 | ||||
| -rw-r--r-- | src/lj_record.c | 38 | ||||
| -rw-r--r-- | src/lj_snap.c | 7 | ||||
| -rw-r--r-- | src/lj_traceerr.h | 1 |
4 files changed, 56 insertions, 16 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 |
diff --git a/src/lj_record.c b/src/lj_record.c index 2e411632..0dcc1ac7 100644 --- a/src/lj_record.c +++ b/src/lj_record.c | |||
| @@ -570,6 +570,17 @@ static void rec_ret(jit_State *J, BCReg rbase, ptrdiff_t gotresults) | |||
| 570 | J->base[--rbase] = TREF_TRUE; /* Prepend true to results. */ | 570 | J->base[--rbase] = TREF_TRUE; /* Prepend true to results. */ |
| 571 | frame = frame_prevd(frame); | 571 | frame = frame_prevd(frame); |
| 572 | } | 572 | } |
| 573 | if (frame_isvarg(frame)) { | ||
| 574 | BCReg cbase = (BCReg)frame_delta(frame); | ||
| 575 | lua_assert(J->framedepth != 1); | ||
| 576 | if (--J->framedepth < 0) /* NYI: return of vararg func to lower frame. */ | ||
| 577 | lj_trace_err(J, LJ_TRERR_NYIRETL); | ||
| 578 | lua_assert(J->baseslot > 1); | ||
| 579 | rbase += cbase; | ||
| 580 | J->baseslot -= (BCReg)cbase; | ||
| 581 | J->base -= cbase; | ||
| 582 | frame = frame_prevd(frame); | ||
| 583 | } | ||
| 573 | if (frame_islua(frame)) { /* Return to Lua frame. */ | 584 | if (frame_islua(frame)) { /* Return to Lua frame. */ |
| 574 | BCIns callins = *(frame_pc(frame)-1); | 585 | BCIns callins = *(frame_pc(frame)-1); |
| 575 | ptrdiff_t nresults = bc_b(callins) ? (ptrdiff_t)bc_b(callins)-1 :gotresults; | 586 | ptrdiff_t nresults = bc_b(callins) ? (ptrdiff_t)bc_b(callins)-1 :gotresults; |
| @@ -1840,7 +1851,6 @@ static void rec_func_setup(jit_State *J) | |||
| 1840 | BCReg s, numparams = pt->numparams; | 1851 | BCReg s, numparams = pt->numparams; |
| 1841 | if ((pt->flags & PROTO_NO_JIT)) | 1852 | if ((pt->flags & PROTO_NO_JIT)) |
| 1842 | lj_trace_err(J, LJ_TRERR_CJITOFF); | 1853 | lj_trace_err(J, LJ_TRERR_CJITOFF); |
| 1843 | lua_assert(!(pt->flags & PROTO_IS_VARARG)); | ||
| 1844 | if (J->baseslot + pt->framesize >= LJ_MAX_JSLOTS) | 1854 | if (J->baseslot + pt->framesize >= LJ_MAX_JSLOTS) |
| 1845 | lj_trace_err(J, LJ_TRERR_STACKOV); | 1855 | lj_trace_err(J, LJ_TRERR_STACKOV); |
| 1846 | /* Fill up missing parameters with nil. */ | 1856 | /* Fill up missing parameters with nil. */ |
| @@ -1850,6 +1860,27 @@ static void rec_func_setup(jit_State *J) | |||
| 1850 | J->maxslot = numparams; | 1860 | J->maxslot = numparams; |
| 1851 | } | 1861 | } |
| 1852 | 1862 | ||
| 1863 | /* Record Lua vararg function setup. */ | ||
| 1864 | static void rec_func_vararg(jit_State *J) | ||
| 1865 | { | ||
| 1866 | GCproto *pt = J->pt; | ||
| 1867 | BCReg s, fixargs, vframe = J->maxslot+1; | ||
| 1868 | lua_assert((pt->flags & PROTO_IS_VARARG)); | ||
| 1869 | if (J->baseslot + vframe + pt->framesize >= LJ_MAX_JSLOTS) | ||
| 1870 | lj_trace_err(J, LJ_TRERR_STACKOV); | ||
| 1871 | J->base[vframe-1] = J->base[-1]; /* Copy function up. */ | ||
| 1872 | /* Copy fixarg slots up and set their original slots to nil. */ | ||
| 1873 | fixargs = pt->numparams < J->maxslot ? pt->numparams : J->maxslot; | ||
| 1874 | for (s = 0; s < fixargs; s++) { | ||
| 1875 | J->base[vframe+s] = J->base[s]; | ||
| 1876 | J->base[s] = TREF_NIL; | ||
| 1877 | } | ||
| 1878 | J->maxslot = fixargs; | ||
| 1879 | J->framedepth++; | ||
| 1880 | J->base += vframe; | ||
| 1881 | J->baseslot += vframe; | ||
| 1882 | } | ||
| 1883 | |||
| 1853 | /* Record entry to a Lua function. */ | 1884 | /* Record entry to a Lua function. */ |
| 1854 | static void rec_func_lua(jit_State *J) | 1885 | static void rec_func_lua(jit_State *J) |
| 1855 | { | 1886 | { |
| @@ -2258,8 +2289,11 @@ void lj_record_ins(jit_State *J) | |||
| 2258 | break; | 2289 | break; |
| 2259 | 2290 | ||
| 2260 | case BC_FUNCV: | 2291 | case BC_FUNCV: |
| 2292 | rec_func_vararg(J); | ||
| 2293 | rec_func_lua(J); | ||
| 2294 | break; | ||
| 2261 | case BC_JFUNCV: | 2295 | case BC_JFUNCV: |
| 2262 | lj_trace_err(J, LJ_TRERR_NYIVF); | 2296 | lua_assert(0); /* Cannot happen. No hotcall counting for varag funcs. */ |
| 2263 | break; | 2297 | break; |
| 2264 | 2298 | ||
| 2265 | case BC_FUNCC: | 2299 | case BC_FUNCC: |
diff --git a/src/lj_snap.c b/src/lj_snap.c index 7c26bfb9..64db5288 100644 --- a/src/lj_snap.c +++ b/src/lj_snap.c | |||
| @@ -87,15 +87,14 @@ static void snapshot_framelinks(jit_State *J, SnapEntry *map) | |||
| 87 | if (frame_islua(frame)) { | 87 | if (frame_islua(frame)) { |
| 88 | map[f++] = SNAP_MKPC(frame_pc(frame)); | 88 | map[f++] = SNAP_MKPC(frame_pc(frame)); |
| 89 | frame = frame_prevl(frame); | 89 | frame = frame_prevl(frame); |
| 90 | } else if (frame_ispcall(frame)) { | ||
| 91 | map[f++] = SNAP_MKFTSZ(frame_ftsz(frame)); | ||
| 92 | frame = frame_prevd(frame); | ||
| 93 | } else if (frame_iscont(frame)) { | 90 | } else if (frame_iscont(frame)) { |
| 94 | map[f++] = SNAP_MKFTSZ(frame_ftsz(frame)); | 91 | map[f++] = SNAP_MKFTSZ(frame_ftsz(frame)); |
| 95 | map[f++] = SNAP_MKPC(frame_contpc(frame)); | 92 | map[f++] = SNAP_MKPC(frame_contpc(frame)); |
| 96 | frame = frame_prevd(frame); | 93 | frame = frame_prevd(frame); |
| 97 | } else { | 94 | } else { |
| 98 | lua_assert(0); | 95 | lua_assert(!frame_isc(frame)); |
| 96 | map[f++] = SNAP_MKFTSZ(frame_ftsz(frame)); | ||
| 97 | frame = frame_prevd(frame); | ||
| 99 | } | 98 | } |
| 100 | } | 99 | } |
| 101 | lua_assert(f == (MSize)(1 + J->framedepth)); | 100 | lua_assert(f == (MSize)(1 + J->framedepth)); |
diff --git a/src/lj_traceerr.h b/src/lj_traceerr.h index 1b0df055..9bfdadc6 100644 --- a/src/lj_traceerr.h +++ b/src/lj_traceerr.h | |||
| @@ -23,7 +23,6 @@ TREDEF(BADTYPE, "bad argument type") | |||
| 23 | TREDEF(CJITOFF, "call to JIT-disabled function") | 23 | TREDEF(CJITOFF, "call to JIT-disabled function") |
| 24 | TREDEF(CUNROLL, "call unroll limit reached") | 24 | TREDEF(CUNROLL, "call unroll limit reached") |
| 25 | TREDEF(DOWNREC, "down-recursion, restarting") | 25 | TREDEF(DOWNREC, "down-recursion, restarting") |
| 26 | TREDEF(NYIVF, "NYI: vararg function") | ||
| 27 | TREDEF(NYICF, "NYI: C function %p") | 26 | TREDEF(NYICF, "NYI: C function %p") |
| 28 | TREDEF(NYIFF, "NYI: FastFunc %s") | 27 | TREDEF(NYIFF, "NYI: FastFunc %s") |
| 29 | TREDEF(NYIFFU, "NYI: unsupported variant of FastFunc %s") | 28 | TREDEF(NYIFFU, "NYI: unsupported variant of FastFunc %s") |
