diff options
author | Mike Pall <mike> | 2010-09-13 00:55:05 +0200 |
---|---|---|
committer | Mike Pall <mike> | 2010-09-13 00:55:05 +0200 |
commit | e32f7d96c1de48e7c425d1e091f9f406d6a6b1d3 (patch) | |
tree | c51b600dec8bdeb65a7645f237ecd4eef279637c /src/lj_record.c | |
parent | 52f75e9a5c5cc2fad846adae8873b572bafde4c2 (diff) | |
download | luajit-e32f7d96c1de48e7c425d1e091f9f406d6a6b1d3.tar.gz luajit-e32f7d96c1de48e7c425d1e091f9f406d6a6b1d3.tar.bz2 luajit-e32f7d96c1de48e7c425d1e091f9f406d6a6b1d3.zip |
Fix tailcalls from vararg functions.
Diffstat (limited to 'src/lj_record.c')
-rw-r--r-- | src/lj_record.c | 9 |
1 files changed, 8 insertions, 1 deletions
diff --git a/src/lj_record.c b/src/lj_record.c index f82468f0..15d72440 100644 --- a/src/lj_record.c +++ b/src/lj_record.c | |||
@@ -520,6 +520,14 @@ static void rec_call(jit_State *J, BCReg func, ptrdiff_t nargs) | |||
520 | static void rec_tailcall(jit_State *J, BCReg func, ptrdiff_t nargs) | 520 | static void rec_tailcall(jit_State *J, BCReg func, ptrdiff_t nargs) |
521 | { | 521 | { |
522 | rec_call_setup(J, func, nargs); | 522 | rec_call_setup(J, func, nargs); |
523 | if (frame_isvarg(J->L->base - 1)) { | ||
524 | BCReg cbase = (BCReg)frame_delta(J->L->base - 1); | ||
525 | if (--J->framedepth < 0) | ||
526 | lj_trace_err(J, LJ_TRERR_NYIRETL); | ||
527 | J->baseslot -= (BCReg)cbase; | ||
528 | J->base -= cbase; | ||
529 | func += cbase; | ||
530 | } | ||
523 | /* Move func + args down. */ | 531 | /* Move func + args down. */ |
524 | memmove(&J->base[-1], &J->base[func], sizeof(TRef)*(J->maxslot+1)); | 532 | memmove(&J->base[-1], &J->base[func], sizeof(TRef)*(J->maxslot+1)); |
525 | /* Note: the new TREF_FRAME is now at J->base[-1] (even for slot #0). */ | 533 | /* Note: the new TREF_FRAME is now at J->base[-1] (even for slot #0). */ |
@@ -572,7 +580,6 @@ static void rec_ret(jit_State *J, BCReg rbase, ptrdiff_t gotresults) | |||
572 | } | 580 | } |
573 | if (frame_isvarg(frame)) { | 581 | if (frame_isvarg(frame)) { |
574 | BCReg cbase = (BCReg)frame_delta(frame); | 582 | 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. */ | 583 | if (--J->framedepth < 0) /* NYI: return of vararg func to lower frame. */ |
577 | lj_trace_err(J, LJ_TRERR_NYIRETL); | 584 | lj_trace_err(J, LJ_TRERR_NYIRETL); |
578 | lua_assert(J->baseslot > 1); | 585 | lua_assert(J->baseslot > 1); |