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.c219
1 files changed, 186 insertions, 33 deletions
diff --git a/src/lj_crecord.c b/src/lj_crecord.c
index 8577de2c..c3b01f63 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)])
@@ -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. */
@@ -862,21 +863,17 @@ again:
862} 863}
863 864
864/* Record setting a finalizer. */ 865/* Record setting a finalizer. */
865static void crec_finalizer(jit_State *J, TRef trcd, cTValue *fin) 866static void crec_finalizer(jit_State *J, TRef trcd, TRef trfin, cTValue *fin)
866{ 867{
867 TRef trlo = lj_ir_call(J, IRCALL_lj_cdata_setfin, trcd); 868 if (tvisgcv(fin)) {
868 TRef trhi = emitir(IRT(IR_ADD, IRT_P32), trlo, lj_ir_kint(J, 4)); 869 if (!trfin) trfin = lj_ir_kptr(J, gcval(fin));
869 if (LJ_BE) { TRef tmp = trlo; trlo = trhi; trhi = tmp; } 870 } else if (tvisnil(fin)) {
870 if (tvisfunc(fin)) { 871 trfin = lj_ir_kptr(J, NULL);
871 emitir(IRT(IR_XSTORE, IRT_P32), trlo, lj_ir_kfunc(J, funcV(fin)));
872 emitir(IRTI(IR_XSTORE), trhi, lj_ir_kint(J, LJ_TFUNC));
873 } else if (tviscdata(fin)) {
874 emitir(IRT(IR_XSTORE, IRT_P32), trlo,
875 lj_ir_kgc(J, obj2gco(cdataV(fin)), IRT_CDATA));
876 emitir(IRTI(IR_XSTORE), trhi, lj_ir_kint(J, LJ_TCDATA));
877 } else { 872 } else {
878 lj_trace_err(J, LJ_TRERR_BADTYPE); 873 lj_trace_err(J, LJ_TRERR_BADTYPE);
879 } 874 }
875 lj_ir_call(J, IRCALL_lj_cdata_setfin, trcd,
876 trfin, lj_ir_kint(J, (int32_t)itype(fin)));
880 J->needsnap = 1; 877 J->needsnap = 1;
881} 878}
882 879
@@ -887,10 +884,8 @@ static void crec_alloc(jit_State *J, RecordFFData *rd, CTypeID id)
887 CTSize sz; 884 CTSize sz;
888 CTInfo info = lj_ctype_info(cts, id, &sz); 885 CTInfo info = lj_ctype_info(cts, id, &sz);
889 CType *d = ctype_raw(cts, id); 886 CType *d = ctype_raw(cts, id);
890 TRef trid; 887 TRef trcd, trid = lj_ir_kint(J, id);
891 if (!sz || sz > 128 || (info & CTF_VLA) || ctype_align(info) > CT_MEMALIGN) 888 cTValue *fin;
892 lj_trace_err(J, LJ_TRERR_NYICONV); /* NYI: large/special allocations. */
893 trid = lj_ir_kint(J, id);
894 /* Use special instruction to box pointer or 32/64 bit integer. */ 889 /* Use special instruction to box pointer or 32/64 bit integer. */
895 if (ctype_isptr(info) || (ctype_isinteger(info) && (sz == 4 || sz == 8))) { 890 if (ctype_isptr(info) || (ctype_isinteger(info) && (sz == 4 || sz == 8))) {
896 TRef sp = J->base[1] ? crec_ct_tv(J, d, 0, J->base[1], &rd->argv[1]) : 891 TRef sp = J->base[1] ? crec_ct_tv(J, d, 0, J->base[1], &rd->argv[1]) :
@@ -898,11 +893,36 @@ static void crec_alloc(jit_State *J, RecordFFData *rd, CTypeID id)
898 sz == 4 ? lj_ir_kint(J, 0) : 893 sz == 4 ? lj_ir_kint(J, 0) :
899 (lj_needsplit(J), lj_ir_kint64(J, 0)); 894 (lj_needsplit(J), lj_ir_kint64(J, 0));
900 J->base[0] = emitir(IRTG(IR_CNEWI, IRT_CDATA), trid, sp); 895 J->base[0] = emitir(IRTG(IR_CNEWI, IRT_CDATA), trid, sp);
896 return;
901 } else { 897 } else {
902 TRef trcd = emitir(IRTG(IR_CNEW, IRT_CDATA), trid, TREF_NIL); 898 TRef trsz = TREF_NIL;
903 cTValue *fin; 899 if ((info & CTF_VLA)) { /* Calculate VLA/VLS size at runtime. */
904 J->base[0] = trcd; 900 CTSize sz0, sz1;
905 if (J->base[1] && !J->base[2] && 901 if (!J->base[1] || J->base[2])
902 lj_trace_err(J, LJ_TRERR_NYICONV); /* NYI: init VLA/VLS. */
903 trsz = crec_ct_tv(J, ctype_get(cts, CTID_INT32), 0,
904 J->base[1], &rd->argv[1]);
905 sz0 = lj_ctype_vlsize(cts, d, 0);
906 sz1 = lj_ctype_vlsize(cts, d, 1);
907 trsz = emitir(IRTGI(IR_MULOV), trsz, lj_ir_kint(J, (int32_t)(sz1-sz0)));
908 trsz = emitir(IRTGI(IR_ADDOV), trsz, lj_ir_kint(J, (int32_t)sz0));
909 J->base[1] = 0; /* Simplify logic below. */
910 } else if (ctype_align(info) > CT_MEMALIGN) {
911 trsz = lj_ir_kint(J, sz);
912 }
913 trcd = emitir(IRTG(IR_CNEW, IRT_CDATA), trid, trsz);
914 if (sz > 128 || (info & CTF_VLA)) {
915 TRef dp;
916 CTSize align;
917 special: /* Only handle bulk zero-fill for large/VLA/VLS types. */
918 if (J->base[1])
919 lj_trace_err(J, LJ_TRERR_NYICONV); /* NYI: init large/VLA/VLS types. */
920 dp = emitir(IRT(IR_ADD, IRT_PTR), trcd, lj_ir_kintp(J, sizeof(GCcdata)));
921 if (trsz == TREF_NIL) trsz = lj_ir_kint(J, sz);
922 align = ctype_align(info);
923 if (align < CT_MEMALIGN) align = CT_MEMALIGN;
924 crec_fill(J, dp, trsz, lj_ir_kint(J, 0), (1u << align));
925 } else if (J->base[1] && !J->base[2] &&
906 !lj_cconv_multi_init(cts, d, &rd->argv[1])) { 926 !lj_cconv_multi_init(cts, d, &rd->argv[1])) {
907 goto single_init; 927 goto single_init;
908 } else if (ctype_isarray(d->info)) { 928 } else if (ctype_isarray(d->info)) {
@@ -913,8 +933,9 @@ static void crec_alloc(jit_State *J, RecordFFData *rd, CTypeID id)
913 TValue *sval = &tv; 933 TValue *sval = &tv;
914 MSize i; 934 MSize i;
915 tv.u64 = 0; 935 tv.u64 = 0;
916 if (!(ctype_isnum(dc->info) || ctype_isptr(dc->info))) 936 if (!(ctype_isnum(dc->info) || ctype_isptr(dc->info)) ||
917 lj_trace_err(J, LJ_TRERR_NYICONV); /* NYI: init array of aggregates. */ 937 esize * CREC_FILL_MAXUNROLL < sz)
938 goto special;
918 for (i = 1, ofs = 0; ofs < sz; ofs += esize) { 939 for (i = 1, ofs = 0; ofs < sz; ofs += esize) {
919 TRef dp = emitir(IRT(IR_ADD, IRT_PTR), trcd, 940 TRef dp = emitir(IRT(IR_ADD, IRT_PTR), trcd,
920 lj_ir_kintp(J, ofs + sizeof(GCcdata))); 941 lj_ir_kintp(J, ofs + sizeof(GCcdata)));
@@ -971,11 +992,12 @@ static void crec_alloc(jit_State *J, RecordFFData *rd, CTypeID id)
971 crec_ct_tv(J, d, dp, lj_ir_kint(J, 0), &tv); 992 crec_ct_tv(J, d, dp, lj_ir_kint(J, 0), &tv);
972 } 993 }
973 } 994 }
974 /* Handle __gc metamethod. */
975 fin = lj_ctype_meta(cts, id, MM_gc);
976 if (fin)
977 crec_finalizer(J, trcd, fin);
978 } 995 }
996 J->base[0] = trcd;
997 /* Handle __gc metamethod. */
998 fin = lj_ctype_meta(cts, id, MM_gc);
999 if (fin)
1000 crec_finalizer(J, trcd, 0, fin);
979} 1001}
980 1002
981/* Record argument conversions. */ 1003/* Record argument conversions. */
@@ -1228,7 +1250,7 @@ static TRef crec_arith_int64(jit_State *J, TRef *sp, CType **s, MMS mm)
1228 for (i = 0; i < 2; i++) { 1250 for (i = 0; i < 2; i++) {
1229 IRType st = tref_type(sp[i]); 1251 IRType st = tref_type(sp[i]);
1230 if (st == IRT_NUM || st == IRT_FLOAT) 1252 if (st == IRT_NUM || st == IRT_FLOAT)
1231 sp[i] = emitconv(sp[i], dt, st, IRCONV_TRUNC|IRCONV_ANY); 1253 sp[i] = emitconv(sp[i], dt, st, IRCONV_ANY);
1232 else if (!(st == IRT_I64 || st == IRT_U64)) 1254 else if (!(st == IRT_I64 || st == IRT_U64))
1233 sp[i] = emitconv(sp[i], dt, IRT_INT, 1255 sp[i] = emitconv(sp[i], dt, IRT_INT,
1234 (s[i]->info & CTF_UNSIGNED) ? 0 : IRCONV_SEXT); 1256 (s[i]->info & CTF_UNSIGNED) ? 0 : IRCONV_SEXT);
@@ -1296,15 +1318,14 @@ static TRef crec_arith_ptr(jit_State *J, TRef *sp, CType **s, MMS mm)
1296 CTypeID id; 1318 CTypeID id;
1297#if LJ_64 1319#if LJ_64
1298 if (t == IRT_NUM || t == IRT_FLOAT) 1320 if (t == IRT_NUM || t == IRT_FLOAT)
1299 tr = emitconv(tr, IRT_INTP, t, IRCONV_TRUNC|IRCONV_ANY); 1321 tr = emitconv(tr, IRT_INTP, t, IRCONV_ANY);
1300 else if (!(t == IRT_I64 || t == IRT_U64)) 1322 else if (!(t == IRT_I64 || t == IRT_U64))
1301 tr = emitconv(tr, IRT_INTP, IRT_INT, 1323 tr = emitconv(tr, IRT_INTP, IRT_INT,
1302 ((t - IRT_I8) & 1) ? 0 : IRCONV_SEXT); 1324 ((t - IRT_I8) & 1) ? 0 : IRCONV_SEXT);
1303#else 1325#else
1304 if (!tref_typerange(sp[1], IRT_I8, IRT_U32)) { 1326 if (!tref_typerange(sp[1], IRT_I8, IRT_U32)) {
1305 tr = emitconv(tr, IRT_INTP, t, 1327 tr = emitconv(tr, IRT_INTP, t,
1306 (t == IRT_NUM || t == IRT_FLOAT) ? 1328 (t == IRT_NUM || t == IRT_FLOAT) ? IRCONV_ANY : 0);
1307 IRCONV_TRUNC|IRCONV_ANY : 0);
1308 } 1329 }
1309#endif 1330#endif
1310 tr = emitir(IRT(IR_MUL, IRT_INTP), tr, lj_ir_kintp(J, sz)); 1331 tr = emitir(IRT(IR_MUL, IRT_INTP), tr, lj_ir_kintp(J, sz));
@@ -1623,7 +1644,139 @@ void LJ_FASTCALL recff_ffi_xof(jit_State *J, RecordFFData *rd)
1623void LJ_FASTCALL recff_ffi_gc(jit_State *J, RecordFFData *rd) 1644void LJ_FASTCALL recff_ffi_gc(jit_State *J, RecordFFData *rd)
1624{ 1645{
1625 argv2cdata(J, J->base[0], &rd->argv[0]); 1646 argv2cdata(J, J->base[0], &rd->argv[0]);
1626 crec_finalizer(J, J->base[0], &rd->argv[1]); 1647 if (!J->base[1])
1648 lj_trace_err(J, LJ_TRERR_BADTYPE);
1649 crec_finalizer(J, J->base[0], J->base[1], &rd->argv[1]);
1650}
1651
1652/* -- 64 bit bit.* library functions -------------------------------------- */
1653
1654/* Determine bit operation type from argument type. */
1655static CTypeID crec_bit64_type(CTState *cts, cTValue *tv)
1656{
1657 if (tviscdata(tv)) {
1658 CType *ct = lj_ctype_rawref(cts, cdataV(tv)->ctypeid);
1659 if (ctype_isenum(ct->info)) ct = ctype_child(cts, ct);
1660 if ((ct->info & (CTMASK_NUM|CTF_BOOL|CTF_FP|CTF_UNSIGNED)) ==
1661 CTINFO(CT_NUM, CTF_UNSIGNED) && ct->size == 8)
1662 return CTID_UINT64; /* Use uint64_t, since it has the highest rank. */
1663 return CTID_INT64; /* Otherwise use int64_t. */
1664 }
1665 return 0; /* Use regular 32 bit ops. */
1666}
1667
1668void LJ_FASTCALL recff_bit64_tobit(jit_State *J, RecordFFData *rd)
1669{
1670 CTState *cts = ctype_ctsG(J2G(J));
1671 TRef tr = crec_ct_tv(J, ctype_get(cts, CTID_INT64), 0,
1672 J->base[0], &rd->argv[0]);
1673 if (!tref_isinteger(tr))
1674 tr = emitconv(tr, IRT_INT, tref_type(tr), 0);
1675 J->base[0] = tr;
1676}
1677
1678int LJ_FASTCALL recff_bit64_unary(jit_State *J, RecordFFData *rd)
1679{
1680 CTState *cts = ctype_ctsG(J2G(J));
1681 CTypeID id = crec_bit64_type(cts, &rd->argv[0]);
1682 if (id) {
1683 TRef tr = crec_ct_tv(J, ctype_get(cts, id), 0, J->base[0], &rd->argv[0]);
1684 tr = emitir(IRT(rd->data, id-CTID_INT64+IRT_I64), tr, 0);
1685 J->base[0] = emitir(IRTG(IR_CNEWI, IRT_CDATA), lj_ir_kint(J, id), tr);
1686 return 1;
1687 }
1688 return 0;
1689}
1690
1691int LJ_FASTCALL recff_bit64_nary(jit_State *J, RecordFFData *rd)
1692{
1693 CTState *cts = ctype_ctsG(J2G(J));
1694 CTypeID id = 0;
1695 MSize i;
1696 for (i = 0; J->base[i] != 0; i++) {
1697 CTypeID aid = crec_bit64_type(cts, &rd->argv[i]);
1698 if (id < aid) id = aid; /* Determine highest type rank of all arguments. */
1699 }
1700 if (id) {
1701 CType *ct = ctype_get(cts, id);
1702 uint32_t ot = IRT(rd->data, id-CTID_INT64+IRT_I64);
1703 TRef tr = crec_ct_tv(J, ct, 0, J->base[0], &rd->argv[0]);
1704 for (i = 1; J->base[i] != 0; i++) {
1705 TRef tr2 = crec_ct_tv(J, ct, 0, J->base[i], &rd->argv[i]);
1706 tr = emitir(ot, tr, tr2);
1707 }
1708 J->base[0] = emitir(IRTG(IR_CNEWI, IRT_CDATA), lj_ir_kint(J, id), tr);
1709 return 1;
1710 }
1711 return 0;
1712}
1713
1714int LJ_FASTCALL recff_bit64_shift(jit_State *J, RecordFFData *rd)
1715{
1716 CTState *cts = ctype_ctsG(J2G(J));
1717 CTypeID id;
1718 TRef tsh = 0;
1719 if (J->base[0] && tref_iscdata(J->base[1])) {
1720 tsh = crec_ct_tv(J, ctype_get(cts, CTID_INT64), 0,
1721 J->base[1], &rd->argv[1]);
1722 if (!tref_isinteger(tsh))
1723 tsh = emitconv(tsh, IRT_INT, tref_type(tsh), 0);
1724 J->base[1] = tsh;
1725 }
1726 id = crec_bit64_type(cts, &rd->argv[0]);
1727 if (id) {
1728 TRef tr = crec_ct_tv(J, ctype_get(cts, id), 0, J->base[0], &rd->argv[0]);
1729 uint32_t op = rd->data;
1730 if (!tsh) tsh = lj_opt_narrow_tobit(J, J->base[1]);
1731 if (!(op < IR_BROL ? LJ_TARGET_MASKSHIFT : LJ_TARGET_MASKROT) &&
1732 !tref_isk(tsh))
1733 tsh = emitir(IRTI(IR_BAND), tsh, lj_ir_kint(J, 63));
1734#ifdef LJ_TARGET_UNIFYROT
1735 if (op == (LJ_TARGET_UNIFYROT == 1 ? IR_BROR : IR_BROL)) {
1736 op = LJ_TARGET_UNIFYROT == 1 ? IR_BROL : IR_BROR;
1737 tsh = emitir(IRTI(IR_NEG), tsh, tsh);
1738 }
1739#endif
1740 tr = emitir(IRT(op, id-CTID_INT64+IRT_I64), tr, tsh);
1741 J->base[0] = emitir(IRTG(IR_CNEWI, IRT_CDATA), lj_ir_kint(J, id), tr);
1742 return 1;
1743 }
1744 return 0;
1745}
1746
1747TRef recff_bit64_tohex(jit_State *J, RecordFFData *rd, TRef hdr)
1748{
1749 CTState *cts = ctype_ctsG(J2G(J));
1750 CTypeID id = crec_bit64_type(cts, &rd->argv[0]);
1751 TRef tr, trsf = J->base[1];
1752 SFormat sf = (STRFMT_UINT|STRFMT_T_HEX);
1753 int32_t n;
1754 if (trsf) {
1755 CTypeID id2 = 0;
1756 n = (int32_t)lj_carith_check64(J->L, 2, &id2);
1757 if (id2)
1758 trsf = crec_ct_tv(J, ctype_get(cts, CTID_INT32), 0, trsf, &rd->argv[1]);
1759 else
1760 trsf = lj_opt_narrow_tobit(J, trsf);
1761 emitir(IRTGI(IR_EQ), trsf, lj_ir_kint(J, n)); /* Specialize to n. */
1762 } else {
1763 n = id ? 16 : 8;
1764 }
1765 if (n < 0) { n = -n; sf |= STRFMT_F_UPPER; }
1766 sf |= ((SFormat)((n+1)&255) << STRFMT_SH_PREC);
1767 if (id) {
1768 tr = crec_ct_tv(J, ctype_get(cts, id), 0, J->base[0], &rd->argv[0]);
1769 if (n < 16)
1770 tr = emitir(IRT(IR_BAND, IRT_U64), tr,
1771 lj_ir_kint64(J, ((uint64_t)1 << 4*n)-1));
1772 } else {
1773 tr = lj_opt_narrow_tobit(J, J->base[0]);
1774 if (n < 8)
1775 tr = emitir(IRTI(IR_BAND), tr, lj_ir_kint(J, (int32_t)((1u << 4*n)-1)));
1776 tr = emitconv(tr, IRT_U64, IRT_INT, 0); /* No sign-extension. */
1777 lj_needsplit(J);
1778 }
1779 return lj_ir_call(J, IRCALL_lj_strfmt_putfxint, hdr, lj_ir_kint(J, sf), tr);
1627} 1780}
1628 1781
1629/* -- Miscellaneous library functions ------------------------------------- */ 1782/* -- Miscellaneous library functions ------------------------------------- */