diff options
Diffstat (limited to 'src')
-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") |