diff options
Diffstat (limited to 'src/lj_record.c')
-rw-r--r-- | src/lj_record.c | 38 |
1 files changed, 36 insertions, 2 deletions
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: |