aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/lj_dispatch.c26
-rw-r--r--src/lj_record.c38
-rw-r--r--src/lj_snap.c7
-rw-r--r--src/lj_traceerr.h1
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. */
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
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. */
1864static 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. */
1854static void rec_func_lua(jit_State *J) 1885static 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")
23TREDEF(CJITOFF, "call to JIT-disabled function") 23TREDEF(CJITOFF, "call to JIT-disabled function")
24TREDEF(CUNROLL, "call unroll limit reached") 24TREDEF(CUNROLL, "call unroll limit reached")
25TREDEF(DOWNREC, "down-recursion, restarting") 25TREDEF(DOWNREC, "down-recursion, restarting")
26TREDEF(NYIVF, "NYI: vararg function")
27TREDEF(NYICF, "NYI: C function %p") 26TREDEF(NYICF, "NYI: C function %p")
28TREDEF(NYIFF, "NYI: FastFunc %s") 27TREDEF(NYIFF, "NYI: FastFunc %s")
29TREDEF(NYIFFU, "NYI: unsupported variant of FastFunc %s") 28TREDEF(NYIFFU, "NYI: unsupported variant of FastFunc %s")