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 | |
| parent | 52f75e9a5c5cc2fad846adae8873b572bafde4c2 (diff) | |
| download | luajit-e32f7d96c1de48e7c425d1e091f9f406d6a6b1d3.tar.gz luajit-e32f7d96c1de48e7c425d1e091f9f406d6a6b1d3.tar.bz2 luajit-e32f7d96c1de48e7c425d1e091f9f406d6a6b1d3.zip | |
Fix tailcalls from vararg functions.
Diffstat (limited to 'src')
| -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); |
