aboutsummaryrefslogtreecommitdiff
path: root/src/lj_crecord.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/lj_crecord.c')
-rw-r--r--src/lj_crecord.c391
1 files changed, 327 insertions, 64 deletions
diff --git a/src/lj_crecord.c b/src/lj_crecord.c
index 3f3552a6..bc21d859 100644
--- a/src/lj_crecord.c
+++ b/src/lj_crecord.c
@@ -11,13 +11,13 @@
11#if LJ_HASJIT && LJ_HASFFI 11#if LJ_HASJIT && LJ_HASFFI
12 12
13#include "lj_err.h" 13#include "lj_err.h"
14#include "lj_str.h"
15#include "lj_tab.h" 14#include "lj_tab.h"
16#include "lj_frame.h" 15#include "lj_frame.h"
17#include "lj_ctype.h" 16#include "lj_ctype.h"
18#include "lj_cdata.h" 17#include "lj_cdata.h"
19#include "lj_cparse.h" 18#include "lj_cparse.h"
20#include "lj_cconv.h" 19#include "lj_cconv.h"
20#include "lj_carith.h"
21#include "lj_clib.h" 21#include "lj_clib.h"
22#include "lj_ccall.h" 22#include "lj_ccall.h"
23#include "lj_ff.h" 23#include "lj_ff.h"
@@ -31,6 +31,7 @@
31#include "lj_snap.h" 31#include "lj_snap.h"
32#include "lj_crecord.h" 32#include "lj_crecord.h"
33#include "lj_dispatch.h" 33#include "lj_dispatch.h"
34#include "lj_strfmt.h"
34 35
35/* Some local macros to save typing. Undef'd at the end. */ 36/* Some local macros to save typing. Undef'd at the end. */
36#define IR(ref) (&J->cur.ir[(ref)]) 37#define IR(ref) (&J->cur.ir[(ref)])
@@ -60,7 +61,8 @@ static GCcdata *argv2cdata(jit_State *J, TRef tr, cTValue *o)
60static CTypeID crec_constructor(jit_State *J, GCcdata *cd, TRef tr) 61static CTypeID crec_constructor(jit_State *J, GCcdata *cd, TRef tr)
61{ 62{
62 CTypeID id; 63 CTypeID id;
63 lua_assert(tref_iscdata(tr) && cd->ctypeid == CTID_CTYPEID); 64 lj_assertJ(tref_iscdata(tr) && cd->ctypeid == CTID_CTYPEID,
65 "expected CTypeID cdata");
64 id = *(CTypeID *)cdataptr(cd); 66 id = *(CTypeID *)cdataptr(cd);
65 tr = emitir(IRT(IR_FLOAD, IRT_INT), tr, IRFL_CDATA_INT); 67 tr = emitir(IRT(IR_FLOAD, IRT_INT), tr, IRFL_CDATA_INT);
66 emitir(IRTG(IR_EQ, IRT_INT), tr, lj_ir_kint(J, (int32_t)id)); 68 emitir(IRTG(IR_EQ, IRT_INT), tr, lj_ir_kint(J, (int32_t)id));
@@ -211,7 +213,7 @@ static void crec_copy_emit(jit_State *J, CRecMemList *ml, MSize mlp,
211 ml[i].trval = emitir(IRT(IR_XLOAD, ml[i].tp), trsptr, 0); 213 ml[i].trval = emitir(IRT(IR_XLOAD, ml[i].tp), trsptr, 0);
212 ml[i].trofs = trofs; 214 ml[i].trofs = trofs;
213 i++; 215 i++;
214 rwin += (LJ_SOFTFP && ml[i].tp == IRT_NUM) ? 2 : 1; 216 rwin += (LJ_SOFTFP32 && ml[i].tp == IRT_NUM) ? 2 : 1;
215 if (rwin >= CREC_COPY_REGWIN || i >= mlp) { /* Flush buffered stores. */ 217 if (rwin >= CREC_COPY_REGWIN || i >= mlp) { /* Flush buffered stores. */
216 rwin = 0; 218 rwin = 0;
217 for ( ; j < i; j++) { 219 for ( ; j < i; j++) {
@@ -236,13 +238,14 @@ static void crec_copy(jit_State *J, TRef trdst, TRef trsrc, TRef trlen,
236 if (len > CREC_COPY_MAXLEN) goto fallback; 238 if (len > CREC_COPY_MAXLEN) goto fallback;
237 if (ct) { 239 if (ct) {
238 CTState *cts = ctype_ctsG(J2G(J)); 240 CTState *cts = ctype_ctsG(J2G(J));
239 lua_assert(ctype_isarray(ct->info) || ctype_isstruct(ct->info)); 241 lj_assertJ(ctype_isarray(ct->info) || ctype_isstruct(ct->info),
242 "copy of non-aggregate");
240 if (ctype_isarray(ct->info)) { 243 if (ctype_isarray(ct->info)) {
241 CType *cct = ctype_rawchild(cts, ct); 244 CType *cct = ctype_rawchild(cts, ct);
242 tp = crec_ct2irt(cts, cct); 245 tp = crec_ct2irt(cts, cct);
243 if (tp == IRT_CDATA) goto rawcopy; 246 if (tp == IRT_CDATA) goto rawcopy;
244 step = lj_ir_type_size[tp]; 247 step = lj_ir_type_size[tp];
245 lua_assert((len & (step-1)) == 0); 248 lj_assertJ((len & (step-1)) == 0, "copy of fractional size");
246 } else if ((ct->info & CTF_UNION)) { 249 } else if ((ct->info & CTF_UNION)) {
247 step = (1u << ctype_align(ct->info)); 250 step = (1u << ctype_align(ct->info));
248 goto rawcopy; 251 goto rawcopy;
@@ -441,7 +444,7 @@ static TRef crec_ct_ct(jit_State *J, CType *d, CType *s, TRef dp, TRef sp,
441 /* fallthrough */ 444 /* fallthrough */
442 case CCX(I, F): 445 case CCX(I, F):
443 if (dt == IRT_CDATA || st == IRT_CDATA) goto err_nyi; 446 if (dt == IRT_CDATA || st == IRT_CDATA) goto err_nyi;
444 sp = emitconv(sp, dsize < 4 ? IRT_INT : dt, st, IRCONV_TRUNC|IRCONV_ANY); 447 sp = emitconv(sp, dsize < 4 ? IRT_INT : dt, st, IRCONV_ANY);
445 goto xstore; 448 goto xstore;
446 case CCX(I, P): 449 case CCX(I, P):
447 case CCX(I, A): 450 case CCX(I, A):
@@ -521,7 +524,7 @@ static TRef crec_ct_ct(jit_State *J, CType *d, CType *s, TRef dp, TRef sp,
521 if (st == IRT_CDATA) goto err_nyi; 524 if (st == IRT_CDATA) goto err_nyi;
522 /* The signed conversion is cheaper. x64 really has 47 bit pointers. */ 525 /* The signed conversion is cheaper. x64 really has 47 bit pointers. */
523 sp = emitconv(sp, (LJ_64 && dsize == 8) ? IRT_I64 : IRT_U32, 526 sp = emitconv(sp, (LJ_64 && dsize == 8) ? IRT_I64 : IRT_U32,
524 st, IRCONV_TRUNC|IRCONV_ANY); 527 st, IRCONV_ANY);
525 goto xstore; 528 goto xstore;
526 529
527 /* Destination is an array. */ 530 /* Destination is an array. */
@@ -613,10 +616,12 @@ static TRef crec_ct_tv(jit_State *J, CType *d, TRef dp, TRef sp, cTValue *sval)
613 sp = lj_ir_kptr(J, NULL); 616 sp = lj_ir_kptr(J, NULL);
614 } else if (tref_isudata(sp)) { 617 } else if (tref_isudata(sp)) {
615 GCudata *ud = udataV(sval); 618 GCudata *ud = udataV(sval);
616 if (ud->udtype == UDTYPE_IO_FILE) { 619 if (ud->udtype == UDTYPE_IO_FILE || ud->udtype == UDTYPE_BUFFER) {
617 TRef tr = emitir(IRT(IR_FLOAD, IRT_U8), sp, IRFL_UDATA_UDTYPE); 620 TRef tr = emitir(IRT(IR_FLOAD, IRT_U8), sp, IRFL_UDATA_UDTYPE);
618 emitir(IRTGI(IR_EQ), tr, lj_ir_kint(J, UDTYPE_IO_FILE)); 621 emitir(IRTGI(IR_EQ), tr, lj_ir_kint(J, ud->udtype));
619 sp = emitir(IRT(IR_FLOAD, IRT_PTR), sp, IRFL_UDATA_FILE); 622 sp = emitir(IRT(IR_FLOAD, IRT_PTR), sp,
623 ud->udtype == UDTYPE_IO_FILE ? IRFL_UDATA_FILE :
624 IRFL_SBUF_R);
620 } else { 625 } else {
621 sp = emitir(IRT(IR_ADD, IRT_PTR), sp, lj_ir_kintp(J, sizeof(GCudata))); 626 sp = emitir(IRT(IR_ADD, IRT_PTR), sp, lj_ir_kintp(J, sizeof(GCudata)));
622 } 627 }
@@ -628,7 +633,8 @@ static TRef crec_ct_tv(jit_State *J, CType *d, TRef dp, TRef sp, cTValue *sval)
628 /* Specialize to the name of the enum constant. */ 633 /* Specialize to the name of the enum constant. */
629 emitir(IRTG(IR_EQ, IRT_STR), sp, lj_ir_kstr(J, str)); 634 emitir(IRTG(IR_EQ, IRT_STR), sp, lj_ir_kstr(J, str));
630 if (cct && ctype_isconstval(cct->info)) { 635 if (cct && ctype_isconstval(cct->info)) {
631 lua_assert(ctype_child(cts, cct)->size == 4); 636 lj_assertJ(ctype_child(cts, cct)->size == 4,
637 "only 32 bit const supported"); /* NYI */
632 svisnz = (void *)(intptr_t)(ofs != 0); 638 svisnz = (void *)(intptr_t)(ofs != 0);
633 sp = lj_ir_kint(J, (int32_t)ofs); 639 sp = lj_ir_kint(J, (int32_t)ofs);
634 sid = ctype_cid(cct->info); 640 sid = ctype_cid(cct->info);
@@ -640,12 +646,22 @@ static TRef crec_ct_tv(jit_State *J, CType *d, TRef dp, TRef sp, cTValue *sval)
640 sp = emitir(IRT(IR_ADD, IRT_PTR), sp, lj_ir_kintp(J, sizeof(GCstr))); 646 sp = emitir(IRT(IR_ADD, IRT_PTR), sp, lj_ir_kintp(J, sizeof(GCstr)));
641 sid = CTID_A_CCHAR; 647 sid = CTID_A_CCHAR;
642 } 648 }
643 } else { /* NYI: tref_istab(sp), tref_islightud(sp). */ 649 } else if (tref_islightud(sp)) {
650#if LJ_64
651 lj_trace_err(J, LJ_TRERR_NYICONV);
652#endif
653 } else { /* NYI: tref_istab(sp). */
644 IRType t; 654 IRType t;
645 sid = argv2cdata(J, sp, sval)->ctypeid; 655 sid = argv2cdata(J, sp, sval)->ctypeid;
646 s = ctype_raw(cts, sid); 656 s = ctype_raw(cts, sid);
647 svisnz = cdataptr(cdataV(sval)); 657 svisnz = cdataptr(cdataV(sval));
648 t = crec_ct2irt(cts, s); 658 if (ctype_isfunc(s->info)) {
659 sid = lj_ctype_intern(cts, CTINFO(CT_PTR, CTALIGN_PTR|sid), CTSIZE_PTR);
660 s = ctype_get(cts, sid);
661 t = IRT_PTR;
662 } else {
663 t = crec_ct2irt(cts, s);
664 }
649 if (ctype_isptr(s->info)) { 665 if (ctype_isptr(s->info)) {
650 sp = emitir(IRT(IR_FLOAD, t), sp, IRFL_CDATA_PTR); 666 sp = emitir(IRT(IR_FLOAD, t), sp, IRFL_CDATA_PTR);
651 if (ctype_isref(s->info)) { 667 if (ctype_isref(s->info)) {
@@ -700,6 +716,19 @@ static TRef crec_reassoc_ofs(jit_State *J, TRef tr, ptrdiff_t *ofsp, MSize sz)
700 return tr; 716 return tr;
701} 717}
702 718
719/* Tailcall to function. */
720static void crec_tailcall(jit_State *J, RecordFFData *rd, cTValue *tv)
721{
722 TRef kfunc = lj_ir_kfunc(J, funcV(tv));
723#if LJ_FR2
724 J->base[-2] = kfunc;
725 J->base[-1] = TREF_FRAME;
726#else
727 J->base[-1] = kfunc | TREF_FRAME;
728#endif
729 rd->nres = -1; /* Pending tailcall. */
730}
731
703/* Record ctype __index/__newindex metamethods. */ 732/* Record ctype __index/__newindex metamethods. */
704static void crec_index_meta(jit_State *J, CTState *cts, CType *ct, 733static void crec_index_meta(jit_State *J, CTState *cts, CType *ct,
705 RecordFFData *rd) 734 RecordFFData *rd)
@@ -709,8 +738,7 @@ static void crec_index_meta(jit_State *J, CTState *cts, CType *ct,
709 if (!tv) 738 if (!tv)
710 lj_trace_err(J, LJ_TRERR_BADTYPE); 739 lj_trace_err(J, LJ_TRERR_BADTYPE);
711 if (tvisfunc(tv)) { 740 if (tvisfunc(tv)) {
712 J->base[-1] = lj_ir_kfunc(J, funcV(tv)) | TREF_FRAME; 741 crec_tailcall(J, rd, tv);
713 rd->nres = -1; /* Pending tailcall. */
714 } else if (rd->data == 0 && tvistab(tv) && tref_isstr(J->base[1])) { 742 } else if (rd->data == 0 && tvistab(tv) && tref_isstr(J->base[1])) {
715 /* Specialize to result of __index lookup. */ 743 /* Specialize to result of __index lookup. */
716 cTValue *o = lj_tab_get(J->L, tabV(tv), &rd->argv[1]); 744 cTValue *o = lj_tab_get(J->L, tabV(tv), &rd->argv[1]);
@@ -727,6 +755,48 @@ static void crec_index_meta(jit_State *J, CTState *cts, CType *ct,
727 } 755 }
728} 756}
729 757
758/* Record bitfield load/store. */
759static void crec_index_bf(jit_State *J, RecordFFData *rd, TRef ptr, CTInfo info)
760{
761 IRType t = IRT_I8 + 2*lj_fls(ctype_bitcsz(info)) + ((info&CTF_UNSIGNED)?1:0);
762 TRef tr = emitir(IRT(IR_XLOAD, t), ptr, 0);
763 CTSize pos = ctype_bitpos(info), bsz = ctype_bitbsz(info), shift = 32 - bsz;
764 lj_assertJ(t <= IRT_U32, "only 32 bit bitfields supported"); /* NYI */
765 if (rd->data == 0) { /* __index metamethod. */
766 if ((info & CTF_BOOL)) {
767 tr = emitir(IRTI(IR_BAND), tr, lj_ir_kint(J, (int32_t)((1u << pos))));
768 /* Assume not equal to zero. Fixup and emit pending guard later. */
769 lj_ir_set(J, IRTGI(IR_NE), tr, lj_ir_kint(J, 0));
770 J->postproc = LJ_POST_FIXGUARD;
771 tr = TREF_TRUE;
772 } else if (!(info & CTF_UNSIGNED)) {
773 tr = emitir(IRTI(IR_BSHL), tr, lj_ir_kint(J, shift - pos));
774 tr = emitir(IRTI(IR_BSAR), tr, lj_ir_kint(J, shift));
775 } else {
776 lj_assertJ(bsz < 32, "unexpected full bitfield index");
777 tr = emitir(IRTI(IR_BSHR), tr, lj_ir_kint(J, pos));
778 tr = emitir(IRTI(IR_BAND), tr, lj_ir_kint(J, (int32_t)((1u << bsz)-1)));
779 /* We can omit the U32 to NUM conversion, since bsz < 32. */
780 }
781 J->base[0] = tr;
782 } else { /* __newindex metamethod. */
783 CTState *cts = ctype_ctsG(J2G(J));
784 CType *ct = ctype_get(cts,
785 (info & CTF_BOOL) ? CTID_BOOL :
786 (info & CTF_UNSIGNED) ? CTID_UINT32 : CTID_INT32);
787 int32_t mask = (int32_t)(((1u << bsz)-1) << pos);
788 TRef sp = crec_ct_tv(J, ct, 0, J->base[2], &rd->argv[2]);
789 sp = emitir(IRTI(IR_BSHL), sp, lj_ir_kint(J, pos));
790 /* Use of the target type avoids forwarding conversions. */
791 sp = emitir(IRT(IR_BAND, t), sp, lj_ir_kint(J, mask));
792 tr = emitir(IRT(IR_BAND, t), tr, lj_ir_kint(J, (int32_t)~mask));
793 tr = emitir(IRT(IR_BOR, t), tr, sp);
794 emitir(IRT(IR_XSTORE, t), ptr, tr);
795 rd->nres = 0;
796 J->needsnap = 1;
797 }
798}
799
730void LJ_FASTCALL recff_cdata_index(jit_State *J, RecordFFData *rd) 800void LJ_FASTCALL recff_cdata_index(jit_State *J, RecordFFData *rd)
731{ 801{
732 TRef idx, ptr = J->base[0]; 802 TRef idx, ptr = J->base[0];
@@ -801,6 +871,7 @@ again:
801 CType *fct; 871 CType *fct;
802 fct = lj_ctype_getfield(cts, ct, name, &fofs); 872 fct = lj_ctype_getfield(cts, ct, name, &fofs);
803 if (fct) { 873 if (fct) {
874 ofs += (ptrdiff_t)fofs;
804 /* Always specialize to the field name. */ 875 /* Always specialize to the field name. */
805 emitir(IRTG(IR_EQ, IRT_STR), idx, lj_ir_kstr(J, name)); 876 emitir(IRTG(IR_EQ, IRT_STR), idx, lj_ir_kstr(J, name));
806 if (ctype_isconstval(fct->info)) { 877 if (ctype_isconstval(fct->info)) {
@@ -812,12 +883,14 @@ again:
812 J->base[0] = lj_ir_kint(J, (int32_t)fct->size); 883 J->base[0] = lj_ir_kint(J, (int32_t)fct->size);
813 return; /* Interpreter will throw for newindex. */ 884 return; /* Interpreter will throw for newindex. */
814 } else if (ctype_isbitfield(fct->info)) { 885 } else if (ctype_isbitfield(fct->info)) {
815 lj_trace_err(J, LJ_TRERR_NYICONV); 886 if (ofs)
887 ptr = emitir(IRT(IR_ADD, IRT_PTR), ptr, lj_ir_kintp(J, ofs));
888 crec_index_bf(J, rd, ptr, fct->info);
889 return;
816 } else { 890 } else {
817 lua_assert(ctype_isfield(fct->info)); 891 lj_assertJ(ctype_isfield(fct->info), "field expected");
818 sid = ctype_cid(fct->info); 892 sid = ctype_cid(fct->info);
819 } 893 }
820 ofs += (ptrdiff_t)fofs;
821 } 894 }
822 } else if (ctype_iscomplex(ct->info)) { 895 } else if (ctype_iscomplex(ct->info)) {
823 if (name->len == 2 && 896 if (name->len == 2 &&
@@ -867,21 +940,17 @@ again:
867} 940}
868 941
869/* Record setting a finalizer. */ 942/* Record setting a finalizer. */
870static void crec_finalizer(jit_State *J, TRef trcd, cTValue *fin) 943static void crec_finalizer(jit_State *J, TRef trcd, TRef trfin, cTValue *fin)
871{ 944{
872 TRef trlo = lj_ir_call(J, IRCALL_lj_cdata_setfin, trcd); 945 if (tvisgcv(fin)) {
873 TRef trhi = emitir(IRT(IR_ADD, IRT_P32), trlo, lj_ir_kint(J, 4)); 946 if (!trfin) trfin = lj_ir_kptr(J, gcval(fin));
874 if (LJ_BE) { TRef tmp = trlo; trlo = trhi; trhi = tmp; } 947 } else if (tvisnil(fin)) {
875 if (tvisfunc(fin)) { 948 trfin = lj_ir_kptr(J, NULL);
876 emitir(IRT(IR_XSTORE, IRT_P32), trlo, lj_ir_kfunc(J, funcV(fin)));
877 emitir(IRTI(IR_XSTORE), trhi, lj_ir_kint(J, LJ_TFUNC));
878 } else if (tviscdata(fin)) {
879 emitir(IRT(IR_XSTORE, IRT_P32), trlo,
880 lj_ir_kgc(J, obj2gco(cdataV(fin)), IRT_CDATA));
881 emitir(IRTI(IR_XSTORE), trhi, lj_ir_kint(J, LJ_TCDATA));
882 } else { 949 } else {
883 lj_trace_err(J, LJ_TRERR_BADTYPE); 950 lj_trace_err(J, LJ_TRERR_BADTYPE);
884 } 951 }
952 lj_ir_call(J, IRCALL_lj_cdata_setfin, trcd,
953 trfin, lj_ir_kint(J, (int32_t)itype(fin)));
885 J->needsnap = 1; 954 J->needsnap = 1;
886} 955}
887 956
@@ -892,10 +961,8 @@ static void crec_alloc(jit_State *J, RecordFFData *rd, CTypeID id)
892 CTSize sz; 961 CTSize sz;
893 CTInfo info = lj_ctype_info(cts, id, &sz); 962 CTInfo info = lj_ctype_info(cts, id, &sz);
894 CType *d = ctype_raw(cts, id); 963 CType *d = ctype_raw(cts, id);
895 TRef trid; 964 TRef trcd, trid = lj_ir_kint(J, id);
896 if (!sz || sz > 128 || (info & CTF_VLA) || ctype_align(info) > CT_MEMALIGN) 965 cTValue *fin;
897 lj_trace_err(J, LJ_TRERR_NYICONV); /* NYI: large/special allocations. */
898 trid = lj_ir_kint(J, id);
899 /* Use special instruction to box pointer or 32/64 bit integer. */ 966 /* Use special instruction to box pointer or 32/64 bit integer. */
900 if (ctype_isptr(info) || (ctype_isinteger(info) && (sz == 4 || sz == 8))) { 967 if (ctype_isptr(info) || (ctype_isinteger(info) && (sz == 4 || sz == 8))) {
901 TRef sp = J->base[1] ? crec_ct_tv(J, d, 0, J->base[1], &rd->argv[1]) : 968 TRef sp = J->base[1] ? crec_ct_tv(J, d, 0, J->base[1], &rd->argv[1]) :
@@ -903,11 +970,36 @@ static void crec_alloc(jit_State *J, RecordFFData *rd, CTypeID id)
903 sz == 4 ? lj_ir_kint(J, 0) : 970 sz == 4 ? lj_ir_kint(J, 0) :
904 (lj_needsplit(J), lj_ir_kint64(J, 0)); 971 (lj_needsplit(J), lj_ir_kint64(J, 0));
905 J->base[0] = emitir(IRTG(IR_CNEWI, IRT_CDATA), trid, sp); 972 J->base[0] = emitir(IRTG(IR_CNEWI, IRT_CDATA), trid, sp);
973 return;
906 } else { 974 } else {
907 TRef trcd = emitir(IRTG(IR_CNEW, IRT_CDATA), trid, TREF_NIL); 975 TRef trsz = TREF_NIL;
908 cTValue *fin; 976 if ((info & CTF_VLA)) { /* Calculate VLA/VLS size at runtime. */
909 J->base[0] = trcd; 977 CTSize sz0, sz1;
910 if (J->base[1] && !J->base[2] && 978 if (!J->base[1] || J->base[2])
979 lj_trace_err(J, LJ_TRERR_NYICONV); /* NYI: init VLA/VLS. */
980 trsz = crec_ct_tv(J, ctype_get(cts, CTID_INT32), 0,
981 J->base[1], &rd->argv[1]);
982 sz0 = lj_ctype_vlsize(cts, d, 0);
983 sz1 = lj_ctype_vlsize(cts, d, 1);
984 trsz = emitir(IRTGI(IR_MULOV), trsz, lj_ir_kint(J, (int32_t)(sz1-sz0)));
985 trsz = emitir(IRTGI(IR_ADDOV), trsz, lj_ir_kint(J, (int32_t)sz0));
986 J->base[1] = 0; /* Simplify logic below. */
987 } else if (ctype_align(info) > CT_MEMALIGN) {
988 trsz = lj_ir_kint(J, sz);
989 }
990 trcd = emitir(IRTG(IR_CNEW, IRT_CDATA), trid, trsz);
991 if (sz > 128 || (info & CTF_VLA)) {
992 TRef dp;
993 CTSize align;
994 special: /* Only handle bulk zero-fill for large/VLA/VLS types. */
995 if (J->base[1])
996 lj_trace_err(J, LJ_TRERR_NYICONV); /* NYI: init large/VLA/VLS types. */
997 dp = emitir(IRT(IR_ADD, IRT_PTR), trcd, lj_ir_kintp(J, sizeof(GCcdata)));
998 if (trsz == TREF_NIL) trsz = lj_ir_kint(J, sz);
999 align = ctype_align(info);
1000 if (align < CT_MEMALIGN) align = CT_MEMALIGN;
1001 crec_fill(J, dp, trsz, lj_ir_kint(J, 0), (1u << align));
1002 } else if (J->base[1] && !J->base[2] &&
911 !lj_cconv_multi_init(cts, d, &rd->argv[1])) { 1003 !lj_cconv_multi_init(cts, d, &rd->argv[1])) {
912 goto single_init; 1004 goto single_init;
913 } else if (ctype_isarray(d->info)) { 1005 } else if (ctype_isarray(d->info)) {
@@ -918,8 +1010,9 @@ static void crec_alloc(jit_State *J, RecordFFData *rd, CTypeID id)
918 TValue *sval = &tv; 1010 TValue *sval = &tv;
919 MSize i; 1011 MSize i;
920 tv.u64 = 0; 1012 tv.u64 = 0;
921 if (!(ctype_isnum(dc->info) || ctype_isptr(dc->info))) 1013 if (!(ctype_isnum(dc->info) || ctype_isptr(dc->info)) ||
922 lj_trace_err(J, LJ_TRERR_NYICONV); /* NYI: init array of aggregates. */ 1014 esize * CREC_FILL_MAXUNROLL < sz)
1015 goto special;
923 for (i = 1, ofs = 0; ofs < sz; ofs += esize) { 1016 for (i = 1, ofs = 0; ofs < sz; ofs += esize) {
924 TRef dp = emitir(IRT(IR_ADD, IRT_PTR), trcd, 1017 TRef dp = emitir(IRT(IR_ADD, IRT_PTR), trcd,
925 lj_ir_kintp(J, ofs + sizeof(GCcdata))); 1018 lj_ir_kintp(J, ofs + sizeof(GCcdata)));
@@ -933,8 +1026,26 @@ static void crec_alloc(jit_State *J, RecordFFData *rd, CTypeID id)
933 crec_ct_tv(J, dc, dp, sp, sval); 1026 crec_ct_tv(J, dc, dp, sp, sval);
934 } 1027 }
935 } else if (ctype_isstruct(d->info)) { 1028 } else if (ctype_isstruct(d->info)) {
936 CTypeID fid = d->sib; 1029 CTypeID fid;
937 MSize i = 1; 1030 MSize i = 1;
1031 if (!J->base[1]) { /* Handle zero-fill of struct-of-NYI. */
1032 fid = d->sib;
1033 while (fid) {
1034 CType *df = ctype_get(cts, fid);
1035 fid = df->sib;
1036 if (ctype_isfield(df->info)) {
1037 CType *dc;
1038 if (!gcref(df->name)) continue; /* Ignore unnamed fields. */
1039 dc = ctype_rawchild(cts, df); /* Field type. */
1040 if (!(ctype_isnum(dc->info) || ctype_isptr(dc->info) ||
1041 ctype_isenum(dc->info)))
1042 goto special;
1043 } else if (!ctype_isconstval(df->info)) {
1044 goto special;
1045 }
1046 }
1047 }
1048 fid = d->sib;
938 while (fid) { 1049 while (fid) {
939 CType *df = ctype_get(cts, fid); 1050 CType *df = ctype_get(cts, fid);
940 fid = df->sib; 1051 fid = df->sib;
@@ -981,11 +1092,12 @@ static void crec_alloc(jit_State *J, RecordFFData *rd, CTypeID id)
981 crec_ct_tv(J, d, dp, lj_ir_kint(J, 0), &tv); 1092 crec_ct_tv(J, d, dp, lj_ir_kint(J, 0), &tv);
982 } 1093 }
983 } 1094 }
984 /* Handle __gc metamethod. */
985 fin = lj_ctype_meta(cts, id, MM_gc);
986 if (fin)
987 crec_finalizer(J, trcd, fin);
988 } 1095 }
1096 J->base[0] = trcd;
1097 /* Handle __gc metamethod. */
1098 fin = lj_ctype_meta(cts, id, MM_gc);
1099 if (fin)
1100 crec_finalizer(J, trcd, 0, fin);
989} 1101}
990 1102
991/* Record argument conversions. */ 1103/* Record argument conversions. */
@@ -1026,7 +1138,7 @@ static TRef crec_call_args(jit_State *J, RecordFFData *rd,
1026 if (fid) { /* Get argument type from field. */ 1138 if (fid) { /* Get argument type from field. */
1027 CType *ctf = ctype_get(cts, fid); 1139 CType *ctf = ctype_get(cts, fid);
1028 fid = ctf->sib; 1140 fid = ctf->sib;
1029 lua_assert(ctype_isfield(ctf->info)); 1141 lj_assertJ(ctype_isfield(ctf->info), "field expected");
1030 did = ctype_cid(ctf->info); 1142 did = ctype_cid(ctf->info);
1031 } else { 1143 } else {
1032 if (!(ct->info & CTF_VARARG)) 1144 if (!(ct->info & CTF_VARARG))
@@ -1045,7 +1157,7 @@ static TRef crec_call_args(jit_State *J, RecordFFData *rd,
1045 else 1157 else
1046 tr = emitconv(tr, IRT_INT, d->size==1 ? IRT_I8 : IRT_I16,IRCONV_SEXT); 1158 tr = emitconv(tr, IRT_INT, d->size==1 ? IRT_I8 : IRT_I16,IRCONV_SEXT);
1047 } 1159 }
1048 } else if (LJ_SOFTFP && ctype_isfp(d->info) && d->size > 4) { 1160 } else if (LJ_SOFTFP32 && ctype_isfp(d->info) && d->size > 4) {
1049 lj_needsplit(J); 1161 lj_needsplit(J);
1050 } 1162 }
1051#if LJ_TARGET_X86 1163#if LJ_TARGET_X86
@@ -1091,20 +1203,20 @@ static void crec_snap_caller(jit_State *J)
1091 lua_State *L = J->L; 1203 lua_State *L = J->L;
1092 TValue *base = L->base, *top = L->top; 1204 TValue *base = L->base, *top = L->top;
1093 const BCIns *pc = J->pc; 1205 const BCIns *pc = J->pc;
1094 TRef ftr = J->base[-1]; 1206 TRef ftr = J->base[-1-LJ_FR2];
1095 ptrdiff_t delta; 1207 ptrdiff_t delta;
1096 if (!frame_islua(base-1) || J->framedepth <= 0) 1208 if (!frame_islua(base-1) || J->framedepth <= 0)
1097 lj_trace_err(J, LJ_TRERR_NYICALL); 1209 lj_trace_err(J, LJ_TRERR_NYICALL);
1098 J->pc = frame_pc(base-1); delta = 1+bc_a(J->pc[-1]); 1210 J->pc = frame_pc(base-1); delta = 1+LJ_FR2+bc_a(J->pc[-1]);
1099 L->top = base; L->base = base - delta; 1211 L->top = base; L->base = base - delta;
1100 J->base[-1] = TREF_FALSE; 1212 J->base[-1-LJ_FR2] = TREF_FALSE;
1101 J->base -= delta; J->baseslot -= (BCReg)delta; 1213 J->base -= delta; J->baseslot -= (BCReg)delta;
1102 J->maxslot = (BCReg)delta; J->framedepth--; 1214 J->maxslot = (BCReg)delta-LJ_FR2; J->framedepth--;
1103 lj_snap_add(J); 1215 lj_snap_add(J);
1104 L->base = base; L->top = top; 1216 L->base = base; L->top = top;
1105 J->framedepth++; J->maxslot = 1; 1217 J->framedepth++; J->maxslot = 1;
1106 J->base += delta; J->baseslot += (BCReg)delta; 1218 J->base += delta; J->baseslot += (BCReg)delta;
1107 J->base[-1] = ftr; J->pc = pc; 1219 J->base[-1-LJ_FR2] = ftr; J->pc = pc;
1108} 1220}
1109 1221
1110/* Record function call. */ 1222/* Record function call. */
@@ -1124,8 +1236,7 @@ static int crec_call(jit_State *J, RecordFFData *rd, GCcdata *cd)
1124 TRef tr; 1236 TRef tr;
1125 TValue tv; 1237 TValue tv;
1126 /* Check for blacklisted C functions that might call a callback. */ 1238 /* Check for blacklisted C functions that might call a callback. */
1127 setlightudV(&tv, 1239 tv.u64 = ((uintptr_t)cdata_getptr(cdataptr(cd), (LJ_64 && tp == IRT_P64) ? 8 : 4) >> 2) | U64x(800000000, 00000000);
1128 cdata_getptr(cdataptr(cd), (LJ_64 && tp == IRT_P64) ? 8 : 4));
1129 if (tvistrue(lj_tab_get(J->L, cts->miscmap, &tv))) 1240 if (tvistrue(lj_tab_get(J->L, cts->miscmap, &tv)))
1130 lj_trace_err(J, LJ_TRERR_BLACKL); 1241 lj_trace_err(J, LJ_TRERR_BLACKL);
1131 if (ctype_isvoid(ctr->info)) { 1242 if (ctype_isvoid(ctr->info)) {
@@ -1196,8 +1307,7 @@ void LJ_FASTCALL recff_cdata_call(jit_State *J, RecordFFData *rd)
1196 tv = lj_ctype_meta(cts, ctype_isptr(ct->info) ? ctype_cid(ct->info) : id, mm); 1307 tv = lj_ctype_meta(cts, ctype_isptr(ct->info) ? ctype_cid(ct->info) : id, mm);
1197 if (tv) { 1308 if (tv) {
1198 if (tvisfunc(tv)) { 1309 if (tvisfunc(tv)) {
1199 J->base[-1] = lj_ir_kfunc(J, funcV(tv)) | TREF_FRAME; 1310 crec_tailcall(J, rd, tv);
1200 rd->nres = -1; /* Pending tailcall. */
1201 return; 1311 return;
1202 } 1312 }
1203 } else if (mm == MM_new) { 1313 } else if (mm == MM_new) {
@@ -1238,7 +1348,7 @@ static TRef crec_arith_int64(jit_State *J, TRef *sp, CType **s, MMS mm)
1238 for (i = 0; i < 2; i++) { 1348 for (i = 0; i < 2; i++) {
1239 IRType st = tref_type(sp[i]); 1349 IRType st = tref_type(sp[i]);
1240 if (st == IRT_NUM || st == IRT_FLOAT) 1350 if (st == IRT_NUM || st == IRT_FLOAT)
1241 sp[i] = emitconv(sp[i], dt, st, IRCONV_TRUNC|IRCONV_ANY); 1351 sp[i] = emitconv(sp[i], dt, st, IRCONV_ANY);
1242 else if (!(st == IRT_I64 || st == IRT_U64)) 1352 else if (!(st == IRT_I64 || st == IRT_U64))
1243 sp[i] = emitconv(sp[i], dt, IRT_INT, 1353 sp[i] = emitconv(sp[i], dt, IRT_INT,
1244 (s[i]->info & CTF_UNSIGNED) ? 0 : IRCONV_SEXT); 1354 (s[i]->info & CTF_UNSIGNED) ? 0 : IRCONV_SEXT);
@@ -1307,15 +1417,14 @@ static TRef crec_arith_ptr(jit_State *J, TRef *sp, CType **s, MMS mm)
1307 CTypeID id; 1417 CTypeID id;
1308#if LJ_64 1418#if LJ_64
1309 if (t == IRT_NUM || t == IRT_FLOAT) 1419 if (t == IRT_NUM || t == IRT_FLOAT)
1310 tr = emitconv(tr, IRT_INTP, t, IRCONV_TRUNC|IRCONV_ANY); 1420 tr = emitconv(tr, IRT_INTP, t, IRCONV_ANY);
1311 else if (!(t == IRT_I64 || t == IRT_U64)) 1421 else if (!(t == IRT_I64 || t == IRT_U64))
1312 tr = emitconv(tr, IRT_INTP, IRT_INT, 1422 tr = emitconv(tr, IRT_INTP, IRT_INT,
1313 ((t - IRT_I8) & 1) ? 0 : IRCONV_SEXT); 1423 ((t - IRT_I8) & 1) ? 0 : IRCONV_SEXT);
1314#else 1424#else
1315 if (!tref_typerange(sp[1], IRT_I8, IRT_U32)) { 1425 if (!tref_typerange(sp[1], IRT_I8, IRT_U32)) {
1316 tr = emitconv(tr, IRT_INTP, t, 1426 tr = emitconv(tr, IRT_INTP, t,
1317 (t == IRT_NUM || t == IRT_FLOAT) ? 1427 (t == IRT_NUM || t == IRT_FLOAT) ? IRCONV_ANY : 0);
1318 IRCONV_TRUNC|IRCONV_ANY : 0);
1319 } 1428 }
1320#endif 1429#endif
1321 tr = emitir(IRT(IR_MUL, IRT_INTP), tr, lj_ir_kintp(J, sz)); 1430 tr = emitir(IRT(IR_MUL, IRT_INTP), tr, lj_ir_kintp(J, sz));
@@ -1347,8 +1456,7 @@ static TRef crec_arith_meta(jit_State *J, TRef *sp, CType **s, CTState *cts,
1347 } 1456 }
1348 if (tv) { 1457 if (tv) {
1349 if (tvisfunc(tv)) { 1458 if (tvisfunc(tv)) {
1350 J->base[-1] = lj_ir_kfunc(J, funcV(tv)) | TREF_FRAME; 1459 crec_tailcall(J, rd, tv);
1351 rd->nres = -1; /* Pending tailcall. */
1352 return 0; 1460 return 0;
1353 } /* NYI: non-function metamethods. */ 1461 } /* NYI: non-function metamethods. */
1354 } else if ((MMS)rd->data == MM_eq) { /* Fallback cdata pointer comparison. */ 1462 } else if ((MMS)rd->data == MM_eq) { /* Fallback cdata pointer comparison. */
@@ -1460,8 +1568,7 @@ void LJ_FASTCALL recff_cdata_arith(jit_State *J, RecordFFData *rd)
1460 !irt_isguard(J->guardemit)) { 1568 !irt_isguard(J->guardemit)) {
1461 const BCIns *pc = frame_contpc(J->L->base-1) - 1; 1569 const BCIns *pc = frame_contpc(J->L->base-1) - 1;
1462 if (bc_op(*pc) <= BC_ISNEP) { 1570 if (bc_op(*pc) <= BC_ISNEP) {
1463 setframe_pc(&J2G(J)->tmptv, pc); 1571 J2G(J)->tmptv.u64 = (uint64_t)(uintptr_t)pc;
1464 J2G(J)->tmptv.u32.lo = ((tref_istrue(tr) ^ bc_op(*pc)) & 1);
1465 J->postproc = LJ_POST_FIXCOMP; 1572 J->postproc = LJ_POST_FIXCOMP;
1466 } 1573 }
1467 } 1574 }
@@ -1650,7 +1757,139 @@ void LJ_FASTCALL recff_ffi_xof(jit_State *J, RecordFFData *rd)
1650void LJ_FASTCALL recff_ffi_gc(jit_State *J, RecordFFData *rd) 1757void LJ_FASTCALL recff_ffi_gc(jit_State *J, RecordFFData *rd)
1651{ 1758{
1652 argv2cdata(J, J->base[0], &rd->argv[0]); 1759 argv2cdata(J, J->base[0], &rd->argv[0]);
1653 crec_finalizer(J, J->base[0], &rd->argv[1]); 1760 if (!J->base[1])
1761 lj_trace_err(J, LJ_TRERR_BADTYPE);
1762 crec_finalizer(J, J->base[0], J->base[1], &rd->argv[1]);
1763}
1764
1765/* -- 64 bit bit.* library functions -------------------------------------- */
1766
1767/* Determine bit operation type from argument type. */
1768static CTypeID crec_bit64_type(CTState *cts, cTValue *tv)
1769{
1770 if (tviscdata(tv)) {
1771 CType *ct = lj_ctype_rawref(cts, cdataV(tv)->ctypeid);
1772 if (ctype_isenum(ct->info)) ct = ctype_child(cts, ct);
1773 if ((ct->info & (CTMASK_NUM|CTF_BOOL|CTF_FP|CTF_UNSIGNED)) ==
1774 CTINFO(CT_NUM, CTF_UNSIGNED) && ct->size == 8)
1775 return CTID_UINT64; /* Use uint64_t, since it has the highest rank. */
1776 return CTID_INT64; /* Otherwise use int64_t. */
1777 }
1778 return 0; /* Use regular 32 bit ops. */
1779}
1780
1781void LJ_FASTCALL recff_bit64_tobit(jit_State *J, RecordFFData *rd)
1782{
1783 CTState *cts = ctype_ctsG(J2G(J));
1784 TRef tr = crec_ct_tv(J, ctype_get(cts, CTID_INT64), 0,
1785 J->base[0], &rd->argv[0]);
1786 if (!tref_isinteger(tr))
1787 tr = emitconv(tr, IRT_INT, tref_type(tr), 0);
1788 J->base[0] = tr;
1789}
1790
1791int LJ_FASTCALL recff_bit64_unary(jit_State *J, RecordFFData *rd)
1792{
1793 CTState *cts = ctype_ctsG(J2G(J));
1794 CTypeID id = crec_bit64_type(cts, &rd->argv[0]);
1795 if (id) {
1796 TRef tr = crec_ct_tv(J, ctype_get(cts, id), 0, J->base[0], &rd->argv[0]);
1797 tr = emitir(IRT(rd->data, id-CTID_INT64+IRT_I64), tr, 0);
1798 J->base[0] = emitir(IRTG(IR_CNEWI, IRT_CDATA), lj_ir_kint(J, id), tr);
1799 return 1;
1800 }
1801 return 0;
1802}
1803
1804int LJ_FASTCALL recff_bit64_nary(jit_State *J, RecordFFData *rd)
1805{
1806 CTState *cts = ctype_ctsG(J2G(J));
1807 CTypeID id = 0;
1808 MSize i;
1809 for (i = 0; J->base[i] != 0; i++) {
1810 CTypeID aid = crec_bit64_type(cts, &rd->argv[i]);
1811 if (id < aid) id = aid; /* Determine highest type rank of all arguments. */
1812 }
1813 if (id) {
1814 CType *ct = ctype_get(cts, id);
1815 uint32_t ot = IRT(rd->data, id-CTID_INT64+IRT_I64);
1816 TRef tr = crec_ct_tv(J, ct, 0, J->base[0], &rd->argv[0]);
1817 for (i = 1; J->base[i] != 0; i++) {
1818 TRef tr2 = crec_ct_tv(J, ct, 0, J->base[i], &rd->argv[i]);
1819 tr = emitir(ot, tr, tr2);
1820 }
1821 J->base[0] = emitir(IRTG(IR_CNEWI, IRT_CDATA), lj_ir_kint(J, id), tr);
1822 return 1;
1823 }
1824 return 0;
1825}
1826
1827int LJ_FASTCALL recff_bit64_shift(jit_State *J, RecordFFData *rd)
1828{
1829 CTState *cts = ctype_ctsG(J2G(J));
1830 CTypeID id;
1831 TRef tsh = 0;
1832 if (J->base[0] && tref_iscdata(J->base[1])) {
1833 tsh = crec_ct_tv(J, ctype_get(cts, CTID_INT64), 0,
1834 J->base[1], &rd->argv[1]);
1835 if (!tref_isinteger(tsh))
1836 tsh = emitconv(tsh, IRT_INT, tref_type(tsh), 0);
1837 J->base[1] = tsh;
1838 }
1839 id = crec_bit64_type(cts, &rd->argv[0]);
1840 if (id) {
1841 TRef tr = crec_ct_tv(J, ctype_get(cts, id), 0, J->base[0], &rd->argv[0]);
1842 uint32_t op = rd->data;
1843 if (!tsh) tsh = lj_opt_narrow_tobit(J, J->base[1]);
1844 if (!(op < IR_BROL ? LJ_TARGET_MASKSHIFT : LJ_TARGET_MASKROT) &&
1845 !tref_isk(tsh))
1846 tsh = emitir(IRTI(IR_BAND), tsh, lj_ir_kint(J, 63));
1847#ifdef LJ_TARGET_UNIFYROT
1848 if (op == (LJ_TARGET_UNIFYROT == 1 ? IR_BROR : IR_BROL)) {
1849 op = LJ_TARGET_UNIFYROT == 1 ? IR_BROL : IR_BROR;
1850 tsh = emitir(IRTI(IR_NEG), tsh, tsh);
1851 }
1852#endif
1853 tr = emitir(IRT(op, id-CTID_INT64+IRT_I64), tr, tsh);
1854 J->base[0] = emitir(IRTG(IR_CNEWI, IRT_CDATA), lj_ir_kint(J, id), tr);
1855 return 1;
1856 }
1857 return 0;
1858}
1859
1860TRef recff_bit64_tohex(jit_State *J, RecordFFData *rd, TRef hdr)
1861{
1862 CTState *cts = ctype_ctsG(J2G(J));
1863 CTypeID id = crec_bit64_type(cts, &rd->argv[0]);
1864 TRef tr, trsf = J->base[1];
1865 SFormat sf = (STRFMT_UINT|STRFMT_T_HEX);
1866 int32_t n;
1867 if (trsf) {
1868 CTypeID id2 = 0;
1869 n = (int32_t)lj_carith_check64(J->L, 2, &id2);
1870 if (id2)
1871 trsf = crec_ct_tv(J, ctype_get(cts, CTID_INT32), 0, trsf, &rd->argv[1]);
1872 else
1873 trsf = lj_opt_narrow_tobit(J, trsf);
1874 emitir(IRTGI(IR_EQ), trsf, lj_ir_kint(J, n)); /* Specialize to n. */
1875 } else {
1876 n = id ? 16 : 8;
1877 }
1878 if (n < 0) { n = -n; sf |= STRFMT_F_UPPER; }
1879 sf |= ((SFormat)((n+1)&255) << STRFMT_SH_PREC);
1880 if (id) {
1881 tr = crec_ct_tv(J, ctype_get(cts, id), 0, J->base[0], &rd->argv[0]);
1882 if (n < 16)
1883 tr = emitir(IRT(IR_BAND, IRT_U64), tr,
1884 lj_ir_kint64(J, ((uint64_t)1 << 4*n)-1));
1885 } else {
1886 tr = lj_opt_narrow_tobit(J, J->base[0]);
1887 if (n < 8)
1888 tr = emitir(IRTI(IR_BAND), tr, lj_ir_kint(J, (int32_t)((1u << 4*n)-1)));
1889 tr = emitconv(tr, IRT_U64, IRT_INT, 0); /* No sign-extension. */
1890 lj_needsplit(J);
1891 }
1892 return lj_ir_call(J, IRCALL_lj_strfmt_putfxint, hdr, lj_ir_kint(J, sf), tr);
1654} 1893}
1655 1894
1656/* -- Miscellaneous library functions ------------------------------------- */ 1895/* -- Miscellaneous library functions ------------------------------------- */
@@ -1674,6 +1913,30 @@ void LJ_FASTCALL lj_crecord_tonumber(jit_State *J, RecordFFData *rd)
1674 } 1913 }
1675} 1914}
1676 1915
1916TRef lj_crecord_loadiu64(jit_State *J, TRef tr, cTValue *o)
1917{
1918 CTypeID id = argv2cdata(J, tr, o)->ctypeid;
1919 if (!(id == CTID_INT64 || id == CTID_UINT64))
1920 lj_trace_err(J, LJ_TRERR_BADTYPE);
1921 lj_needsplit(J);
1922 return emitir(IRT(IR_FLOAD, id == CTID_INT64 ? IRT_I64 : IRT_U64), tr,
1923 IRFL_CDATA_INT64);
1924}
1925
1926#if LJ_HASBUFFER
1927TRef lj_crecord_topcvoid(jit_State *J, TRef tr, cTValue *o)
1928{
1929 CTState *cts = ctype_ctsG(J2G(J));
1930 if (!tref_iscdata(tr)) lj_trace_err(J, LJ_TRERR_BADTYPE);
1931 return crec_ct_tv(J, ctype_get(cts, CTID_P_CVOID), 0, tr, o);
1932}
1933
1934TRef lj_crecord_topuint8(jit_State *J, TRef tr)
1935{
1936 return emitir(IRTG(IR_CNEWI, IRT_CDATA), lj_ir_kint(J, CTID_P_UINT8), tr);
1937}
1938#endif
1939
1677#undef IR 1940#undef IR
1678#undef emitir 1941#undef emitir
1679#undef emitconv 1942#undef emitconv