diff options
author | Mike Pall <mike> | 2010-09-13 01:17:38 +0200 |
---|---|---|
committer | Mike Pall <mike> | 2010-09-13 01:17:38 +0200 |
commit | 847b9cf2534233198e0229c209ab4c4040f5166e (patch) | |
tree | 8e07f98f6624029a26979bade9e6b1a618bb7a89 /src/lj_record.c | |
parent | e32f7d96c1de48e7c425d1e091f9f406d6a6b1d3 (diff) | |
download | luajit-847b9cf2534233198e0229c209ab4c4040f5166e.tar.gz luajit-847b9cf2534233198e0229c209ab4c4040f5166e.tar.bz2 luajit-847b9cf2534233198e0229c209ab4c4040f5166e.zip |
Record vararg expressions with varargs defined off-trace.
Add SLOAD variant to access the frame type/size.
Diffstat (limited to 'src/lj_record.c')
-rw-r--r-- | src/lj_record.c | 80 |
1 files changed, 57 insertions, 23 deletions
diff --git a/src/lj_record.c b/src/lj_record.c index 15d72440..739279ad 100644 --- a/src/lj_record.c +++ b/src/lj_record.c | |||
@@ -650,29 +650,6 @@ static void rec_ret(jit_State *J, BCReg rbase, ptrdiff_t gotresults) | |||
650 | lua_assert(J->baseslot >= 1); | 650 | lua_assert(J->baseslot >= 1); |
651 | } | 651 | } |
652 | 652 | ||
653 | /* -- Vararg handling ----------------------------------------------------- */ | ||
654 | |||
655 | /* Record vararg instruction. */ | ||
656 | static void rec_varg(jit_State *J, BCReg dst, ptrdiff_t nresults) | ||
657 | { | ||
658 | ptrdiff_t nvararg = frame_delta(J->L->base-1) - J->pt->numparams - 1; | ||
659 | lua_assert(frame_isvarg(J->L->base-1)); | ||
660 | if (J->framedepth == 0) { /* NYI: unknown number of varargs. */ | ||
661 | setintV(&J->errinfo, BC_VARG); | ||
662 | lj_trace_err_info(J, LJ_TRERR_NYIBC); | ||
663 | } else { /* Simple case: known fixed number of varargs defined on-trace. */ | ||
664 | ptrdiff_t i; | ||
665 | if (nresults == -1) { | ||
666 | nresults = nvararg; | ||
667 | J->maxslot = dst + nvararg; | ||
668 | } else if (dst + nresults > J->maxslot) { | ||
669 | J->maxslot = dst + nresults; | ||
670 | } | ||
671 | for (i = 0; i < nresults; i++) | ||
672 | J->base[dst+i] = i < nvararg ? J->base[i - nvararg - 1] : TREF_NIL; | ||
673 | } | ||
674 | } | ||
675 | |||
676 | /* -- Metamethod handling ------------------------------------------------- */ | 653 | /* -- Metamethod handling ------------------------------------------------- */ |
677 | 654 | ||
678 | /* Prepare to record call to metamethod. */ | 655 | /* Prepare to record call to metamethod. */ |
@@ -1928,6 +1905,63 @@ static void rec_func_jit(jit_State *J, TraceNo lnk) | |||
1928 | rec_stop(J, lnk); /* Link to the function. */ | 1905 | rec_stop(J, lnk); /* Link to the function. */ |
1929 | } | 1906 | } |
1930 | 1907 | ||
1908 | /* -- Vararg handling ----------------------------------------------------- */ | ||
1909 | |||
1910 | /* Record vararg instruction. */ | ||
1911 | static void rec_varg(jit_State *J, BCReg dst, ptrdiff_t nresults) | ||
1912 | { | ||
1913 | int32_t numparams = J->pt->numparams; | ||
1914 | ptrdiff_t nvararg = frame_delta(J->L->base-1) - numparams - 1; | ||
1915 | lua_assert(frame_isvarg(J->L->base-1)); | ||
1916 | if (J->framedepth > 0) { /* Simple case: varargs defined on-trace. */ | ||
1917 | ptrdiff_t i; | ||
1918 | if (nvararg < 0) nvararg = 0; | ||
1919 | if (nresults == -1) { | ||
1920 | nresults = nvararg; | ||
1921 | J->maxslot = dst + (BCReg)nvararg; | ||
1922 | } else if (dst + nresults > J->maxslot) { | ||
1923 | J->maxslot = dst + (BCReg)nresults; | ||
1924 | } | ||
1925 | for (i = 0; i < nresults; i++) { | ||
1926 | J->base[dst+i] = i < nvararg ? J->base[i - nvararg - 1] : TREF_NIL; | ||
1927 | lua_assert(J->base[dst+i] != 0); | ||
1928 | } | ||
1929 | } else { /* Unknown number of varargs passed to trace. */ | ||
1930 | TRef fr = emitir(IRTI(IR_SLOAD), 0, IRSLOAD_READONLY|IRSLOAD_FRAME); | ||
1931 | int32_t frofs = 8*(1+numparams)+FRAME_VARG; | ||
1932 | if (nresults >= 0) { /* Known fixed number of results. */ | ||
1933 | ptrdiff_t i; | ||
1934 | if (nvararg > 0) { | ||
1935 | TRef vbase; | ||
1936 | if (nvararg >= nresults) | ||
1937 | emitir(IRTGI(IR_GE), fr, lj_ir_kint(J, frofs+8*(int32_t)nresults)); | ||
1938 | else | ||
1939 | emitir(IRTGI(IR_EQ), fr, lj_ir_kint(J, frame_ftsz(J->L->base-1))); | ||
1940 | vbase = emitir(IRTI(IR_SUB), REF_BASE, fr); | ||
1941 | vbase = emitir(IRT(IR_ADD, IRT_PTR), vbase, lj_ir_kint(J, frofs-8)); | ||
1942 | for (i = 0; i < nvararg; i++) { | ||
1943 | IRType t = itype2irt(&J->L->base[i-1-nvararg]); | ||
1944 | TRef aref = emitir(IRT(IR_AREF, IRT_PTR), | ||
1945 | vbase, lj_ir_kint(J, (int32_t)i)); | ||
1946 | TRef tr = emitir(IRTG(IR_ALOAD, t), aref, 0); | ||
1947 | if (irtype_ispri(t)) tr = TREF_PRI(t); /* Canonicalize primitives. */ | ||
1948 | J->base[dst+i] = tr; | ||
1949 | } | ||
1950 | } else { | ||
1951 | emitir(IRTGI(IR_LE), fr, lj_ir_kint(J, frofs)); | ||
1952 | nvararg = 0; | ||
1953 | } | ||
1954 | for (i = nvararg; i < nresults; i++) | ||
1955 | J->base[dst+i] = TREF_NIL; | ||
1956 | if (dst + (BCReg)nresults > J->maxslot) | ||
1957 | J->maxslot = dst + (BCReg)nresults; | ||
1958 | } else { | ||
1959 | setintV(&J->errinfo, BC_VARG); | ||
1960 | lj_trace_err_info(J, LJ_TRERR_NYIBC); | ||
1961 | } | ||
1962 | } | ||
1963 | } | ||
1964 | |||
1931 | /* -- Record allocations -------------------------------------------------- */ | 1965 | /* -- Record allocations -------------------------------------------------- */ |
1932 | 1966 | ||
1933 | static TRef rec_tnew(jit_State *J, uint32_t ah) | 1967 | static TRef rec_tnew(jit_State *J, uint32_t ah) |