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.c322
1 files changed, 270 insertions, 52 deletions
diff --git a/src/lj_crecord.c b/src/lj_crecord.c
index 99344b79..6e999cc9 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)])
@@ -211,7 +212,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); 212 ml[i].trval = emitir(IRT(IR_XLOAD, ml[i].tp), trsptr, 0);
212 ml[i].trofs = trofs; 213 ml[i].trofs = trofs;
213 i++; 214 i++;
214 rwin += (LJ_SOFTFP && ml[i].tp == IRT_NUM) ? 2 : 1; 215 rwin += (LJ_SOFTFP32 && ml[i].tp == IRT_NUM) ? 2 : 1;
215 if (rwin >= CREC_COPY_REGWIN || i >= mlp) { /* Flush buffered stores. */ 216 if (rwin >= CREC_COPY_REGWIN || i >= mlp) { /* Flush buffered stores. */
216 rwin = 0; 217 rwin = 0;
217 for ( ; j < i; j++) { 218 for ( ; j < i; j++) {
@@ -441,7 +442,7 @@ static TRef crec_ct_ct(jit_State *J, CType *d, CType *s, TRef dp, TRef sp,
441 /* fallthrough */ 442 /* fallthrough */
442 case CCX(I, F): 443 case CCX(I, F):
443 if (dt == IRT_CDATA || st == IRT_CDATA) goto err_nyi; 444 if (dt == IRT_CDATA || st == IRT_CDATA) goto err_nyi;
444 sp = emitconv(sp, dsize < 4 ? IRT_INT : dt, st, IRCONV_TRUNC|IRCONV_ANY); 445 sp = emitconv(sp, dsize < 4 ? IRT_INT : dt, st, IRCONV_ANY);
445 goto xstore; 446 goto xstore;
446 case CCX(I, P): 447 case CCX(I, P):
447 case CCX(I, A): 448 case CCX(I, A):
@@ -521,7 +522,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; 522 if (st == IRT_CDATA) goto err_nyi;
522 /* The signed conversion is cheaper. x64 really has 47 bit pointers. */ 523 /* The signed conversion is cheaper. x64 really has 47 bit pointers. */
523 sp = emitconv(sp, (LJ_64 && dsize == 8) ? IRT_I64 : IRT_U32, 524 sp = emitconv(sp, (LJ_64 && dsize == 8) ? IRT_I64 : IRT_U32,
524 st, IRCONV_TRUNC|IRCONV_ANY); 525 st, IRCONV_ANY);
525 goto xstore; 526 goto xstore;
526 527
527 /* Destination is an array. */ 528 /* Destination is an array. */
@@ -640,12 +641,23 @@ 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))); 641 sp = emitir(IRT(IR_ADD, IRT_PTR), sp, lj_ir_kintp(J, sizeof(GCstr)));
641 sid = CTID_A_CCHAR; 642 sid = CTID_A_CCHAR;
642 } 643 }
643 } else { /* NYI: tref_istab(sp), tref_islightud(sp). */ 644 } else if (tref_islightud(sp)) {
645#if LJ_64
646 sp = emitir(IRT(IR_BAND, IRT_P64), sp,
647 lj_ir_kint64(J, U64x(00007fff,ffffffff)));
648#endif
649 } else { /* NYI: tref_istab(sp). */
644 IRType t; 650 IRType t;
645 sid = argv2cdata(J, sp, sval)->ctypeid; 651 sid = argv2cdata(J, sp, sval)->ctypeid;
646 s = ctype_raw(cts, sid); 652 s = ctype_raw(cts, sid);
647 svisnz = cdataptr(cdataV(sval)); 653 svisnz = cdataptr(cdataV(sval));
648 t = crec_ct2irt(cts, s); 654 if (ctype_isfunc(s->info)) {
655 sid = lj_ctype_intern(cts, CTINFO(CT_PTR, CTALIGN_PTR|sid), CTSIZE_PTR);
656 s = ctype_get(cts, sid);
657 t = IRT_PTR;
658 } else {
659 t = crec_ct2irt(cts, s);
660 }
649 if (ctype_isptr(s->info)) { 661 if (ctype_isptr(s->info)) {
650 sp = emitir(IRT(IR_FLOAD, t), sp, IRFL_CDATA_PTR); 662 sp = emitir(IRT(IR_FLOAD, t), sp, IRFL_CDATA_PTR);
651 if (ctype_isref(s->info)) { 663 if (ctype_isref(s->info)) {
@@ -700,6 +712,19 @@ static TRef crec_reassoc_ofs(jit_State *J, TRef tr, ptrdiff_t *ofsp, MSize sz)
700 return tr; 712 return tr;
701} 713}
702 714
715/* Tailcall to function. */
716static void crec_tailcall(jit_State *J, RecordFFData *rd, cTValue *tv)
717{
718 TRef kfunc = lj_ir_kfunc(J, funcV(tv));
719#if LJ_FR2
720 J->base[-2] = kfunc;
721 J->base[-1] = TREF_FRAME;
722#else
723 J->base[-1] = kfunc | TREF_FRAME;
724#endif
725 rd->nres = -1; /* Pending tailcall. */
726}
727
703/* Record ctype __index/__newindex metamethods. */ 728/* Record ctype __index/__newindex metamethods. */
704static void crec_index_meta(jit_State *J, CTState *cts, CType *ct, 729static void crec_index_meta(jit_State *J, CTState *cts, CType *ct,
705 RecordFFData *rd) 730 RecordFFData *rd)
@@ -709,8 +734,7 @@ static void crec_index_meta(jit_State *J, CTState *cts, CType *ct,
709 if (!tv) 734 if (!tv)
710 lj_trace_err(J, LJ_TRERR_BADTYPE); 735 lj_trace_err(J, LJ_TRERR_BADTYPE);
711 if (tvisfunc(tv)) { 736 if (tvisfunc(tv)) {
712 J->base[-1] = lj_ir_kfunc(J, funcV(tv)) | TREF_FRAME; 737 crec_tailcall(J, rd, tv);
713 rd->nres = -1; /* Pending tailcall. */
714 } else if (rd->data == 0 && tvistab(tv) && tref_isstr(J->base[1])) { 738 } else if (rd->data == 0 && tvistab(tv) && tref_isstr(J->base[1])) {
715 /* Specialize to result of __index lookup. */ 739 /* Specialize to result of __index lookup. */
716 cTValue *o = lj_tab_get(J->L, tabV(tv), &rd->argv[1]); 740 cTValue *o = lj_tab_get(J->L, tabV(tv), &rd->argv[1]);
@@ -727,6 +751,48 @@ static void crec_index_meta(jit_State *J, CTState *cts, CType *ct,
727 } 751 }
728} 752}
729 753
754/* Record bitfield load/store. */
755static void crec_index_bf(jit_State *J, RecordFFData *rd, TRef ptr, CTInfo info)
756{
757 IRType t = IRT_I8 + 2*lj_fls(ctype_bitcsz(info)) + ((info&CTF_UNSIGNED)?1:0);
758 TRef tr = emitir(IRT(IR_XLOAD, t), ptr, 0);
759 CTSize pos = ctype_bitpos(info), bsz = ctype_bitbsz(info), shift = 32 - bsz;
760 lua_assert(t <= IRT_U32); /* NYI: 64 bit bitfields. */
761 if (rd->data == 0) { /* __index metamethod. */
762 if ((info & CTF_BOOL)) {
763 tr = emitir(IRTI(IR_BAND), tr, lj_ir_kint(J, (int32_t)((1u << pos))));
764 /* Assume not equal to zero. Fixup and emit pending guard later. */
765 lj_ir_set(J, IRTGI(IR_NE), tr, lj_ir_kint(J, 0));
766 J->postproc = LJ_POST_FIXGUARD;
767 tr = TREF_TRUE;
768 } else if (!(info & CTF_UNSIGNED)) {
769 tr = emitir(IRTI(IR_BSHL), tr, lj_ir_kint(J, shift - pos));
770 tr = emitir(IRTI(IR_BSAR), tr, lj_ir_kint(J, shift));
771 } else {
772 lua_assert(bsz < 32); /* Full-size fields cannot end up here. */
773 tr = emitir(IRTI(IR_BSHR), tr, lj_ir_kint(J, pos));
774 tr = emitir(IRTI(IR_BAND), tr, lj_ir_kint(J, (int32_t)((1u << bsz)-1)));
775 /* We can omit the U32 to NUM conversion, since bsz < 32. */
776 }
777 J->base[0] = tr;
778 } else { /* __newindex metamethod. */
779 CTState *cts = ctype_ctsG(J2G(J));
780 CType *ct = ctype_get(cts,
781 (info & CTF_BOOL) ? CTID_BOOL :
782 (info & CTF_UNSIGNED) ? CTID_UINT32 : CTID_INT32);
783 int32_t mask = (int32_t)(((1u << bsz)-1) << pos);
784 TRef sp = crec_ct_tv(J, ct, 0, J->base[2], &rd->argv[2]);
785 sp = emitir(IRTI(IR_BSHL), sp, lj_ir_kint(J, pos));
786 /* Use of the target type avoids forwarding conversions. */
787 sp = emitir(IRT(IR_BAND, t), sp, lj_ir_kint(J, mask));
788 tr = emitir(IRT(IR_BAND, t), tr, lj_ir_kint(J, (int32_t)~mask));
789 tr = emitir(IRT(IR_BOR, t), tr, sp);
790 emitir(IRT(IR_XSTORE, t), ptr, tr);
791 rd->nres = 0;
792 J->needsnap = 1;
793 }
794}
795
730void LJ_FASTCALL recff_cdata_index(jit_State *J, RecordFFData *rd) 796void LJ_FASTCALL recff_cdata_index(jit_State *J, RecordFFData *rd)
731{ 797{
732 TRef idx, ptr = J->base[0]; 798 TRef idx, ptr = J->base[0];
@@ -801,6 +867,7 @@ again:
801 CType *fct; 867 CType *fct;
802 fct = lj_ctype_getfield(cts, ct, name, &fofs); 868 fct = lj_ctype_getfield(cts, ct, name, &fofs);
803 if (fct) { 869 if (fct) {
870 ofs += (ptrdiff_t)fofs;
804 /* Always specialize to the field name. */ 871 /* Always specialize to the field name. */
805 emitir(IRTG(IR_EQ, IRT_STR), idx, lj_ir_kstr(J, name)); 872 emitir(IRTG(IR_EQ, IRT_STR), idx, lj_ir_kstr(J, name));
806 if (ctype_isconstval(fct->info)) { 873 if (ctype_isconstval(fct->info)) {
@@ -812,12 +879,14 @@ again:
812 J->base[0] = lj_ir_kint(J, (int32_t)fct->size); 879 J->base[0] = lj_ir_kint(J, (int32_t)fct->size);
813 return; /* Interpreter will throw for newindex. */ 880 return; /* Interpreter will throw for newindex. */
814 } else if (ctype_isbitfield(fct->info)) { 881 } else if (ctype_isbitfield(fct->info)) {
815 lj_trace_err(J, LJ_TRERR_NYICONV); 882 if (ofs)
883 ptr = emitir(IRT(IR_ADD, IRT_PTR), ptr, lj_ir_kintp(J, ofs));
884 crec_index_bf(J, rd, ptr, fct->info);
885 return;
816 } else { 886 } else {
817 lua_assert(ctype_isfield(fct->info)); 887 lua_assert(ctype_isfield(fct->info));
818 sid = ctype_cid(fct->info); 888 sid = ctype_cid(fct->info);
819 } 889 }
820 ofs += (ptrdiff_t)fofs;
821 } 890 }
822 } else if (ctype_iscomplex(ct->info)) { 891 } else if (ctype_iscomplex(ct->info)) {
823 if (name->len == 2 && 892 if (name->len == 2 &&
@@ -867,21 +936,17 @@ again:
867} 936}
868 937
869/* Record setting a finalizer. */ 938/* Record setting a finalizer. */
870static void crec_finalizer(jit_State *J, TRef trcd, cTValue *fin) 939static void crec_finalizer(jit_State *J, TRef trcd, TRef trfin, cTValue *fin)
871{ 940{
872 TRef trlo = lj_ir_call(J, IRCALL_lj_cdata_setfin, trcd); 941 if (tvisgcv(fin)) {
873 TRef trhi = emitir(IRT(IR_ADD, IRT_P32), trlo, lj_ir_kint(J, 4)); 942 if (!trfin) trfin = lj_ir_kptr(J, gcval(fin));
874 if (LJ_BE) { TRef tmp = trlo; trlo = trhi; trhi = tmp; } 943 } else if (tvisnil(fin)) {
875 if (tvisfunc(fin)) { 944 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 { 945 } else {
883 lj_trace_err(J, LJ_TRERR_BADTYPE); 946 lj_trace_err(J, LJ_TRERR_BADTYPE);
884 } 947 }
948 lj_ir_call(J, IRCALL_lj_cdata_setfin, trcd,
949 trfin, lj_ir_kint(J, (int32_t)itype(fin)));
885 J->needsnap = 1; 950 J->needsnap = 1;
886} 951}
887 952
@@ -892,10 +957,8 @@ static void crec_alloc(jit_State *J, RecordFFData *rd, CTypeID id)
892 CTSize sz; 957 CTSize sz;
893 CTInfo info = lj_ctype_info(cts, id, &sz); 958 CTInfo info = lj_ctype_info(cts, id, &sz);
894 CType *d = ctype_raw(cts, id); 959 CType *d = ctype_raw(cts, id);
895 TRef trid; 960 TRef trcd, trid = lj_ir_kint(J, id);
896 if (!sz || sz > 128 || (info & CTF_VLA) || ctype_align(info) > CT_MEMALIGN) 961 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. */ 962 /* Use special instruction to box pointer or 32/64 bit integer. */
900 if (ctype_isptr(info) || (ctype_isinteger(info) && (sz == 4 || sz == 8))) { 963 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]) : 964 TRef sp = J->base[1] ? crec_ct_tv(J, d, 0, J->base[1], &rd->argv[1]) :
@@ -903,11 +966,36 @@ static void crec_alloc(jit_State *J, RecordFFData *rd, CTypeID id)
903 sz == 4 ? lj_ir_kint(J, 0) : 966 sz == 4 ? lj_ir_kint(J, 0) :
904 (lj_needsplit(J), lj_ir_kint64(J, 0)); 967 (lj_needsplit(J), lj_ir_kint64(J, 0));
905 J->base[0] = emitir(IRTG(IR_CNEWI, IRT_CDATA), trid, sp); 968 J->base[0] = emitir(IRTG(IR_CNEWI, IRT_CDATA), trid, sp);
969 return;
906 } else { 970 } else {
907 TRef trcd = emitir(IRTG(IR_CNEW, IRT_CDATA), trid, TREF_NIL); 971 TRef trsz = TREF_NIL;
908 cTValue *fin; 972 if ((info & CTF_VLA)) { /* Calculate VLA/VLS size at runtime. */
909 J->base[0] = trcd; 973 CTSize sz0, sz1;
910 if (J->base[1] && !J->base[2] && 974 if (!J->base[1] || J->base[2])
975 lj_trace_err(J, LJ_TRERR_NYICONV); /* NYI: init VLA/VLS. */
976 trsz = crec_ct_tv(J, ctype_get(cts, CTID_INT32), 0,
977 J->base[1], &rd->argv[1]);
978 sz0 = lj_ctype_vlsize(cts, d, 0);
979 sz1 = lj_ctype_vlsize(cts, d, 1);
980 trsz = emitir(IRTGI(IR_MULOV), trsz, lj_ir_kint(J, (int32_t)(sz1-sz0)));
981 trsz = emitir(IRTGI(IR_ADDOV), trsz, lj_ir_kint(J, (int32_t)sz0));
982 J->base[1] = 0; /* Simplify logic below. */
983 } else if (ctype_align(info) > CT_MEMALIGN) {
984 trsz = lj_ir_kint(J, sz);
985 }
986 trcd = emitir(IRTG(IR_CNEW, IRT_CDATA), trid, trsz);
987 if (sz > 128 || (info & CTF_VLA)) {
988 TRef dp;
989 CTSize align;
990 special: /* Only handle bulk zero-fill for large/VLA/VLS types. */
991 if (J->base[1])
992 lj_trace_err(J, LJ_TRERR_NYICONV); /* NYI: init large/VLA/VLS types. */
993 dp = emitir(IRT(IR_ADD, IRT_PTR), trcd, lj_ir_kintp(J, sizeof(GCcdata)));
994 if (trsz == TREF_NIL) trsz = lj_ir_kint(J, sz);
995 align = ctype_align(info);
996 if (align < CT_MEMALIGN) align = CT_MEMALIGN;
997 crec_fill(J, dp, trsz, lj_ir_kint(J, 0), (1u << align));
998 } else if (J->base[1] && !J->base[2] &&
911 !lj_cconv_multi_init(cts, d, &rd->argv[1])) { 999 !lj_cconv_multi_init(cts, d, &rd->argv[1])) {
912 goto single_init; 1000 goto single_init;
913 } else if (ctype_isarray(d->info)) { 1001 } else if (ctype_isarray(d->info)) {
@@ -918,8 +1006,9 @@ static void crec_alloc(jit_State *J, RecordFFData *rd, CTypeID id)
918 TValue *sval = &tv; 1006 TValue *sval = &tv;
919 MSize i; 1007 MSize i;
920 tv.u64 = 0; 1008 tv.u64 = 0;
921 if (!(ctype_isnum(dc->info) || ctype_isptr(dc->info))) 1009 if (!(ctype_isnum(dc->info) || ctype_isptr(dc->info)) ||
922 lj_trace_err(J, LJ_TRERR_NYICONV); /* NYI: init array of aggregates. */ 1010 esize * CREC_FILL_MAXUNROLL < sz)
1011 goto special;
923 for (i = 1, ofs = 0; ofs < sz; ofs += esize) { 1012 for (i = 1, ofs = 0; ofs < sz; ofs += esize) {
924 TRef dp = emitir(IRT(IR_ADD, IRT_PTR), trcd, 1013 TRef dp = emitir(IRT(IR_ADD, IRT_PTR), trcd,
925 lj_ir_kintp(J, ofs + sizeof(GCcdata))); 1014 lj_ir_kintp(J, ofs + sizeof(GCcdata)));
@@ -976,11 +1065,12 @@ static void crec_alloc(jit_State *J, RecordFFData *rd, CTypeID id)
976 crec_ct_tv(J, d, dp, lj_ir_kint(J, 0), &tv); 1065 crec_ct_tv(J, d, dp, lj_ir_kint(J, 0), &tv);
977 } 1066 }
978 } 1067 }
979 /* Handle __gc metamethod. */
980 fin = lj_ctype_meta(cts, id, MM_gc);
981 if (fin)
982 crec_finalizer(J, trcd, fin);
983 } 1068 }
1069 J->base[0] = trcd;
1070 /* Handle __gc metamethod. */
1071 fin = lj_ctype_meta(cts, id, MM_gc);
1072 if (fin)
1073 crec_finalizer(J, trcd, 0, fin);
984} 1074}
985 1075
986/* Record argument conversions. */ 1076/* Record argument conversions. */
@@ -1040,7 +1130,7 @@ static TRef crec_call_args(jit_State *J, RecordFFData *rd,
1040 else 1130 else
1041 tr = emitconv(tr, IRT_INT, d->size==1 ? IRT_I8 : IRT_I16,IRCONV_SEXT); 1131 tr = emitconv(tr, IRT_INT, d->size==1 ? IRT_I8 : IRT_I16,IRCONV_SEXT);
1042 } 1132 }
1043 } else if (LJ_SOFTFP && ctype_isfp(d->info) && d->size > 4) { 1133 } else if (LJ_SOFTFP32 && ctype_isfp(d->info) && d->size > 4) {
1044 lj_needsplit(J); 1134 lj_needsplit(J);
1045 } 1135 }
1046#if LJ_TARGET_X86 1136#if LJ_TARGET_X86
@@ -1086,20 +1176,20 @@ static void crec_snap_caller(jit_State *J)
1086 lua_State *L = J->L; 1176 lua_State *L = J->L;
1087 TValue *base = L->base, *top = L->top; 1177 TValue *base = L->base, *top = L->top;
1088 const BCIns *pc = J->pc; 1178 const BCIns *pc = J->pc;
1089 TRef ftr = J->base[-1]; 1179 TRef ftr = J->base[-1-LJ_FR2];
1090 ptrdiff_t delta; 1180 ptrdiff_t delta;
1091 if (!frame_islua(base-1) || J->framedepth <= 0) 1181 if (!frame_islua(base-1) || J->framedepth <= 0)
1092 lj_trace_err(J, LJ_TRERR_NYICALL); 1182 lj_trace_err(J, LJ_TRERR_NYICALL);
1093 J->pc = frame_pc(base-1); delta = 1+bc_a(J->pc[-1]); 1183 J->pc = frame_pc(base-1); delta = 1+LJ_FR2+bc_a(J->pc[-1]);
1094 L->top = base; L->base = base - delta; 1184 L->top = base; L->base = base - delta;
1095 J->base[-1] = TREF_FALSE; 1185 J->base[-1-LJ_FR2] = TREF_FALSE;
1096 J->base -= delta; J->baseslot -= (BCReg)delta; 1186 J->base -= delta; J->baseslot -= (BCReg)delta;
1097 J->maxslot = (BCReg)delta; J->framedepth--; 1187 J->maxslot = (BCReg)delta-LJ_FR2; J->framedepth--;
1098 lj_snap_add(J); 1188 lj_snap_add(J);
1099 L->base = base; L->top = top; 1189 L->base = base; L->top = top;
1100 J->framedepth++; J->maxslot = 1; 1190 J->framedepth++; J->maxslot = 1;
1101 J->base += delta; J->baseslot += (BCReg)delta; 1191 J->base += delta; J->baseslot += (BCReg)delta;
1102 J->base[-1] = ftr; J->pc = pc; 1192 J->base[-1-LJ_FR2] = ftr; J->pc = pc;
1103} 1193}
1104 1194
1105/* Record function call. */ 1195/* Record function call. */
@@ -1191,8 +1281,7 @@ void LJ_FASTCALL recff_cdata_call(jit_State *J, RecordFFData *rd)
1191 tv = lj_ctype_meta(cts, ctype_isptr(ct->info) ? ctype_cid(ct->info) : id, mm); 1281 tv = lj_ctype_meta(cts, ctype_isptr(ct->info) ? ctype_cid(ct->info) : id, mm);
1192 if (tv) { 1282 if (tv) {
1193 if (tvisfunc(tv)) { 1283 if (tvisfunc(tv)) {
1194 J->base[-1] = lj_ir_kfunc(J, funcV(tv)) | TREF_FRAME; 1284 crec_tailcall(J, rd, tv);
1195 rd->nres = -1; /* Pending tailcall. */
1196 return; 1285 return;
1197 } 1286 }
1198 } else if (mm == MM_new) { 1287 } else if (mm == MM_new) {
@@ -1233,7 +1322,7 @@ static TRef crec_arith_int64(jit_State *J, TRef *sp, CType **s, MMS mm)
1233 for (i = 0; i < 2; i++) { 1322 for (i = 0; i < 2; i++) {
1234 IRType st = tref_type(sp[i]); 1323 IRType st = tref_type(sp[i]);
1235 if (st == IRT_NUM || st == IRT_FLOAT) 1324 if (st == IRT_NUM || st == IRT_FLOAT)
1236 sp[i] = emitconv(sp[i], dt, st, IRCONV_TRUNC|IRCONV_ANY); 1325 sp[i] = emitconv(sp[i], dt, st, IRCONV_ANY);
1237 else if (!(st == IRT_I64 || st == IRT_U64)) 1326 else if (!(st == IRT_I64 || st == IRT_U64))
1238 sp[i] = emitconv(sp[i], dt, IRT_INT, 1327 sp[i] = emitconv(sp[i], dt, IRT_INT,
1239 (s[i]->info & CTF_UNSIGNED) ? 0 : IRCONV_SEXT); 1328 (s[i]->info & CTF_UNSIGNED) ? 0 : IRCONV_SEXT);
@@ -1302,15 +1391,14 @@ static TRef crec_arith_ptr(jit_State *J, TRef *sp, CType **s, MMS mm)
1302 CTypeID id; 1391 CTypeID id;
1303#if LJ_64 1392#if LJ_64
1304 if (t == IRT_NUM || t == IRT_FLOAT) 1393 if (t == IRT_NUM || t == IRT_FLOAT)
1305 tr = emitconv(tr, IRT_INTP, t, IRCONV_TRUNC|IRCONV_ANY); 1394 tr = emitconv(tr, IRT_INTP, t, IRCONV_ANY);
1306 else if (!(t == IRT_I64 || t == IRT_U64)) 1395 else if (!(t == IRT_I64 || t == IRT_U64))
1307 tr = emitconv(tr, IRT_INTP, IRT_INT, 1396 tr = emitconv(tr, IRT_INTP, IRT_INT,
1308 ((t - IRT_I8) & 1) ? 0 : IRCONV_SEXT); 1397 ((t - IRT_I8) & 1) ? 0 : IRCONV_SEXT);
1309#else 1398#else
1310 if (!tref_typerange(sp[1], IRT_I8, IRT_U32)) { 1399 if (!tref_typerange(sp[1], IRT_I8, IRT_U32)) {
1311 tr = emitconv(tr, IRT_INTP, t, 1400 tr = emitconv(tr, IRT_INTP, t,
1312 (t == IRT_NUM || t == IRT_FLOAT) ? 1401 (t == IRT_NUM || t == IRT_FLOAT) ? IRCONV_ANY : 0);
1313 IRCONV_TRUNC|IRCONV_ANY : 0);
1314 } 1402 }
1315#endif 1403#endif
1316 tr = emitir(IRT(IR_MUL, IRT_INTP), tr, lj_ir_kintp(J, sz)); 1404 tr = emitir(IRT(IR_MUL, IRT_INTP), tr, lj_ir_kintp(J, sz));
@@ -1342,8 +1430,7 @@ static TRef crec_arith_meta(jit_State *J, TRef *sp, CType **s, CTState *cts,
1342 } 1430 }
1343 if (tv) { 1431 if (tv) {
1344 if (tvisfunc(tv)) { 1432 if (tvisfunc(tv)) {
1345 J->base[-1] = lj_ir_kfunc(J, funcV(tv)) | TREF_FRAME; 1433 crec_tailcall(J, rd, tv);
1346 rd->nres = -1; /* Pending tailcall. */
1347 return 0; 1434 return 0;
1348 } /* NYI: non-function metamethods. */ 1435 } /* NYI: non-function metamethods. */
1349 } else if ((MMS)rd->data == MM_eq) { /* Fallback cdata pointer comparison. */ 1436 } else if ((MMS)rd->data == MM_eq) { /* Fallback cdata pointer comparison. */
@@ -1453,8 +1540,7 @@ void LJ_FASTCALL recff_cdata_arith(jit_State *J, RecordFFData *rd)
1453 !irt_isguard(J->guardemit)) { 1540 !irt_isguard(J->guardemit)) {
1454 const BCIns *pc = frame_contpc(J->L->base-1) - 1; 1541 const BCIns *pc = frame_contpc(J->L->base-1) - 1;
1455 if (bc_op(*pc) <= BC_ISNEP) { 1542 if (bc_op(*pc) <= BC_ISNEP) {
1456 setframe_pc(&J2G(J)->tmptv, pc); 1543 J2G(J)->tmptv.u64 = (uint64_t)(uintptr_t)pc;
1457 J2G(J)->tmptv.u32.lo = ((tref_istrue(tr) ^ bc_op(*pc)) & 1);
1458 J->postproc = LJ_POST_FIXCOMP; 1544 J->postproc = LJ_POST_FIXCOMP;
1459 } 1545 }
1460 } 1546 }
@@ -1643,7 +1729,139 @@ void LJ_FASTCALL recff_ffi_xof(jit_State *J, RecordFFData *rd)
1643void LJ_FASTCALL recff_ffi_gc(jit_State *J, RecordFFData *rd) 1729void LJ_FASTCALL recff_ffi_gc(jit_State *J, RecordFFData *rd)
1644{ 1730{
1645 argv2cdata(J, J->base[0], &rd->argv[0]); 1731 argv2cdata(J, J->base[0], &rd->argv[0]);
1646 crec_finalizer(J, J->base[0], &rd->argv[1]); 1732 if (!J->base[1])
1733 lj_trace_err(J, LJ_TRERR_BADTYPE);
1734 crec_finalizer(J, J->base[0], J->base[1], &rd->argv[1]);
1735}
1736
1737/* -- 64 bit bit.* library functions -------------------------------------- */
1738
1739/* Determine bit operation type from argument type. */
1740static CTypeID crec_bit64_type(CTState *cts, cTValue *tv)
1741{
1742 if (tviscdata(tv)) {
1743 CType *ct = lj_ctype_rawref(cts, cdataV(tv)->ctypeid);
1744 if (ctype_isenum(ct->info)) ct = ctype_child(cts, ct);
1745 if ((ct->info & (CTMASK_NUM|CTF_BOOL|CTF_FP|CTF_UNSIGNED)) ==
1746 CTINFO(CT_NUM, CTF_UNSIGNED) && ct->size == 8)
1747 return CTID_UINT64; /* Use uint64_t, since it has the highest rank. */
1748 return CTID_INT64; /* Otherwise use int64_t. */
1749 }
1750 return 0; /* Use regular 32 bit ops. */
1751}
1752
1753void LJ_FASTCALL recff_bit64_tobit(jit_State *J, RecordFFData *rd)
1754{
1755 CTState *cts = ctype_ctsG(J2G(J));
1756 TRef tr = crec_ct_tv(J, ctype_get(cts, CTID_INT64), 0,
1757 J->base[0], &rd->argv[0]);
1758 if (!tref_isinteger(tr))
1759 tr = emitconv(tr, IRT_INT, tref_type(tr), 0);
1760 J->base[0] = tr;
1761}
1762
1763int LJ_FASTCALL recff_bit64_unary(jit_State *J, RecordFFData *rd)
1764{
1765 CTState *cts = ctype_ctsG(J2G(J));
1766 CTypeID id = crec_bit64_type(cts, &rd->argv[0]);
1767 if (id) {
1768 TRef tr = crec_ct_tv(J, ctype_get(cts, id), 0, J->base[0], &rd->argv[0]);
1769 tr = emitir(IRT(rd->data, id-CTID_INT64+IRT_I64), tr, 0);
1770 J->base[0] = emitir(IRTG(IR_CNEWI, IRT_CDATA), lj_ir_kint(J, id), tr);
1771 return 1;
1772 }
1773 return 0;
1774}
1775
1776int LJ_FASTCALL recff_bit64_nary(jit_State *J, RecordFFData *rd)
1777{
1778 CTState *cts = ctype_ctsG(J2G(J));
1779 CTypeID id = 0;
1780 MSize i;
1781 for (i = 0; J->base[i] != 0; i++) {
1782 CTypeID aid = crec_bit64_type(cts, &rd->argv[i]);
1783 if (id < aid) id = aid; /* Determine highest type rank of all arguments. */
1784 }
1785 if (id) {
1786 CType *ct = ctype_get(cts, id);
1787 uint32_t ot = IRT(rd->data, id-CTID_INT64+IRT_I64);
1788 TRef tr = crec_ct_tv(J, ct, 0, J->base[0], &rd->argv[0]);
1789 for (i = 1; J->base[i] != 0; i++) {
1790 TRef tr2 = crec_ct_tv(J, ct, 0, J->base[i], &rd->argv[i]);
1791 tr = emitir(ot, tr, tr2);
1792 }
1793 J->base[0] = emitir(IRTG(IR_CNEWI, IRT_CDATA), lj_ir_kint(J, id), tr);
1794 return 1;
1795 }
1796 return 0;
1797}
1798
1799int LJ_FASTCALL recff_bit64_shift(jit_State *J, RecordFFData *rd)
1800{
1801 CTState *cts = ctype_ctsG(J2G(J));
1802 CTypeID id;
1803 TRef tsh = 0;
1804 if (J->base[0] && tref_iscdata(J->base[1])) {
1805 tsh = crec_ct_tv(J, ctype_get(cts, CTID_INT64), 0,
1806 J->base[1], &rd->argv[1]);
1807 if (!tref_isinteger(tsh))
1808 tsh = emitconv(tsh, IRT_INT, tref_type(tsh), 0);
1809 J->base[1] = tsh;
1810 }
1811 id = crec_bit64_type(cts, &rd->argv[0]);
1812 if (id) {
1813 TRef tr = crec_ct_tv(J, ctype_get(cts, id), 0, J->base[0], &rd->argv[0]);
1814 uint32_t op = rd->data;
1815 if (!tsh) tsh = lj_opt_narrow_tobit(J, J->base[1]);
1816 if (!(op < IR_BROL ? LJ_TARGET_MASKSHIFT : LJ_TARGET_MASKROT) &&
1817 !tref_isk(tsh))
1818 tsh = emitir(IRTI(IR_BAND), tsh, lj_ir_kint(J, 63));
1819#ifdef LJ_TARGET_UNIFYROT
1820 if (op == (LJ_TARGET_UNIFYROT == 1 ? IR_BROR : IR_BROL)) {
1821 op = LJ_TARGET_UNIFYROT == 1 ? IR_BROL : IR_BROR;
1822 tsh = emitir(IRTI(IR_NEG), tsh, tsh);
1823 }
1824#endif
1825 tr = emitir(IRT(op, id-CTID_INT64+IRT_I64), tr, tsh);
1826 J->base[0] = emitir(IRTG(IR_CNEWI, IRT_CDATA), lj_ir_kint(J, id), tr);
1827 return 1;
1828 }
1829 return 0;
1830}
1831
1832TRef recff_bit64_tohex(jit_State *J, RecordFFData *rd, TRef hdr)
1833{
1834 CTState *cts = ctype_ctsG(J2G(J));
1835 CTypeID id = crec_bit64_type(cts, &rd->argv[0]);
1836 TRef tr, trsf = J->base[1];
1837 SFormat sf = (STRFMT_UINT|STRFMT_T_HEX);
1838 int32_t n;
1839 if (trsf) {
1840 CTypeID id2 = 0;
1841 n = (int32_t)lj_carith_check64(J->L, 2, &id2);
1842 if (id2)
1843 trsf = crec_ct_tv(J, ctype_get(cts, CTID_INT32), 0, trsf, &rd->argv[1]);
1844 else
1845 trsf = lj_opt_narrow_tobit(J, trsf);
1846 emitir(IRTGI(IR_EQ), trsf, lj_ir_kint(J, n)); /* Specialize to n. */
1847 } else {
1848 n = id ? 16 : 8;
1849 }
1850 if (n < 0) { n = -n; sf |= STRFMT_F_UPPER; }
1851 sf |= ((SFormat)((n+1)&255) << STRFMT_SH_PREC);
1852 if (id) {
1853 tr = crec_ct_tv(J, ctype_get(cts, id), 0, J->base[0], &rd->argv[0]);
1854 if (n < 16)
1855 tr = emitir(IRT(IR_BAND, IRT_U64), tr,
1856 lj_ir_kint64(J, ((uint64_t)1 << 4*n)-1));
1857 } else {
1858 tr = lj_opt_narrow_tobit(J, J->base[0]);
1859 if (n < 8)
1860 tr = emitir(IRTI(IR_BAND), tr, lj_ir_kint(J, (int32_t)((1u << 4*n)-1)));
1861 tr = emitconv(tr, IRT_U64, IRT_INT, 0); /* No sign-extension. */
1862 lj_needsplit(J);
1863 }
1864 return lj_ir_call(J, IRCALL_lj_strfmt_putfxint, hdr, lj_ir_kint(J, sf), tr);
1647} 1865}
1648 1866
1649/* -- Miscellaneous library functions ------------------------------------- */ 1867/* -- Miscellaneous library functions ------------------------------------- */