aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/lib_string.c10
-rw-r--r--src/lj_ffrecord.c78
-rw-r--r--src/lj_ircall.h7
-rw-r--r--src/lj_opt_fold.c43
4 files changed, 133 insertions, 5 deletions
diff --git a/src/lib_string.c b/src/lib_string.c
index cc1affbd..204f6975 100644
--- a/src/lib_string.c
+++ b/src/lib_string.c
@@ -658,10 +658,10 @@ static GCstr *string_fmt_tostring(lua_State *L, int arg, int retry)
658 return lj_strfmt_obj(L, o); 658 return lj_strfmt_obj(L, o);
659} 659}
660 660
661LJLIB_CF(string_format) 661LJLIB_CF(string_format) LJLIB_REC(.)
662{ 662{
663 int arg, top = (int)(L->top - L->base); 663 int arg, top = (int)(L->top - L->base);
664 GCstr *sfmt; 664 GCstr *fmt;
665 SBuf *sb; 665 SBuf *sb;
666 FormatState fs; 666 FormatState fs;
667 SFormat sf; 667 SFormat sf;
@@ -669,8 +669,8 @@ LJLIB_CF(string_format)
669again: 669again:
670 arg = 1; 670 arg = 1;
671 sb = lj_buf_tmp_(L); 671 sb = lj_buf_tmp_(L);
672 sfmt = lj_lib_checkstr(L, arg); 672 fmt = lj_lib_checkstr(L, arg);
673 lj_strfmt_init(&fs, strdata(sfmt), sfmt->len); 673 lj_strfmt_init(&fs, strdata(fmt), fmt->len);
674 while ((sf = lj_strfmt_parse(&fs)) != STRFMT_EOF) { 674 while ((sf = lj_strfmt_parse(&fs)) != STRFMT_EOF) {
675 if (sf == STRFMT_LIT) { 675 if (sf == STRFMT_LIT) {
676 lj_buf_putmem(sb, fs.str, fs.len); 676 lj_buf_putmem(sb, fs.str, fs.len);
@@ -705,7 +705,7 @@ again:
705 if (str == NULL) 705 if (str == NULL)
706 retry = 1; 706 retry = 1;
707 else if ((sf & STRFMT_T_QUOTED)) 707 else if ((sf & STRFMT_T_QUOTED))
708 lj_strfmt_putquoted(sb, str); 708 lj_strfmt_putquoted(sb, str); /* No formatting. */
709 else 709 else
710 lj_strfmt_putfstr(sb, sf, str); 710 lj_strfmt_putfstr(sb, sf, str);
711 break; 711 break;
diff --git a/src/lj_ffrecord.c b/src/lj_ffrecord.c
index 97c24836..31f9b390 100644
--- a/src/lj_ffrecord.c
+++ b/src/lj_ffrecord.c
@@ -871,6 +871,84 @@ static void LJ_FASTCALL recff_string_find(jit_State *J, RecordFFData *rd)
871 } 871 }
872} 872}
873 873
874static void LJ_FASTCALL recff_string_format(jit_State *J, RecordFFData *rd)
875{
876 TRef trfmt = lj_ir_tostr(J, J->base[0]);
877 GCstr *fmt = argv2str(J, &rd->argv[0]);
878 int arg = 1;
879 TRef hdr, tr;
880 FormatState fs;
881 SFormat sf;
882 /* Specialize to the format string. */
883 emitir(IRTG(IR_EQ, IRT_STR), trfmt, lj_ir_kstr(J, fmt));
884 tr = hdr = recff_bufhdr(J);
885 lj_strfmt_init(&fs, strdata(fmt), fmt->len);
886 while ((sf = lj_strfmt_parse(&fs)) != STRFMT_EOF) { /* Parse format. */
887 TRef tra = sf == STRFMT_LIT ? 0 : J->base[arg++];
888 TRef trsf = lj_ir_kint(J, (int32_t)sf);
889 IRCallID id;
890 switch (STRFMT_TYPE(sf)) {
891 case STRFMT_LIT:
892 tr = emitir(IRT(IR_BUFPUT, IRT_P32), tr,
893 lj_ir_kstr(J, lj_str_new(J->L, fs.str, fs.len)));
894 break;
895 case STRFMT_INT:
896 id = IRCALL_lj_strfmt_putfnum_int;
897 handle_int:
898 if (!tref_isinteger(tra))
899 goto handle_num;
900 if (sf == STRFMT_INT) { /* Shortcut for plain %d. */
901 tr = emitir(IRT(IR_BUFPUT, IRT_P32), tr,
902 emitir(IRT(IR_TOSTR, IRT_STR), tra, IRTOSTR_INT));
903 } else {
904#if LJ_HASFFI
905 tra = emitir(IRT(IR_CONV, IRT_U64), tra,
906 (IRT_INT|(IRT_U64<<5)|IRCONV_SEXT));
907 tr = lj_ir_call(J, IRCALL_lj_strfmt_putfxint, tr, trsf, tra);
908 lj_needsplit(J);
909#else
910 recff_nyiu(J); /* Don't bother working around this NYI. */
911#endif
912 }
913 break;
914 case STRFMT_UINT:
915 id = IRCALL_lj_strfmt_putfnum_uint;
916 goto handle_int;
917 case STRFMT_NUM:
918 id = IRCALL_lj_strfmt_putfnum;
919 handle_num:
920 tra = lj_ir_tonum(J, tra);
921 tr = lj_ir_call(J, id, tr, trsf, tra);
922 if (LJ_SOFTFP) lj_needsplit(J);
923 break;
924 case STRFMT_STR:
925 if (!tref_isstr(tra))
926 recff_nyiu(J); /* NYI: __tostring and non-string types for %s. */
927 if (sf == STRFMT_STR) /* Shortcut for plain %s. */
928 tr = emitir(IRT(IR_BUFPUT, IRT_P32), tr, tra);
929 else if ((sf & STRFMT_T_QUOTED))
930 tr = lj_ir_call(J, IRCALL_lj_strfmt_putquoted, tr, tra);
931 else
932 tr = lj_ir_call(J, IRCALL_lj_strfmt_putfstr, tr, trsf, tra);
933 break;
934 case STRFMT_CHAR:
935 tra = lj_opt_narrow_toint(J, tra);
936 if (sf == STRFMT_CHAR) /* Shortcut for plain %c. */
937 tr = emitir(IRT(IR_BUFPUT, IRT_P32), tr,
938 emitir(IRT(IR_TOSTR, IRT_STR), tra, IRTOSTR_CHAR));
939 else
940 tr = lj_ir_call(J, IRCALL_lj_strfmt_putfchar, tr, trsf, tra);
941 break;
942 case STRFMT_PTR: /* NYI */
943 case STRFMT_ERR:
944 default:
945 recff_nyiu(J);
946 break;
947 }
948 }
949 J->base[0] = emitir(IRT(IR_BUFSTR, IRT_STR), tr, hdr);
950}
951
874/* -- Table library fast functions ---------------------------------------- */ 952/* -- Table library fast functions ---------------------------------------- */
875 953
876static void LJ_FASTCALL recff_table_insert(jit_State *J, RecordFFData *rd) 954static void LJ_FASTCALL recff_table_insert(jit_State *J, RecordFFData *rd)
diff --git a/src/lj_ircall.h b/src/lj_ircall.h
index 43bd25d9..7271ceca 100644
--- a/src/lj_ircall.h
+++ b/src/lj_ircall.h
@@ -124,6 +124,13 @@ typedef struct CCallInfo {
124 _(ANY, lj_strfmt_char, 2, FN, STR, CCI_L) \ 124 _(ANY, lj_strfmt_char, 2, FN, STR, CCI_L) \
125 _(ANY, lj_strfmt_putint, 2, FL, P32, 0) \ 125 _(ANY, lj_strfmt_putint, 2, FL, P32, 0) \
126 _(ANY, lj_strfmt_putnum, 2, FL, P32, 0) \ 126 _(ANY, lj_strfmt_putnum, 2, FL, P32, 0) \
127 _(ANY, lj_strfmt_putquoted, 2, FL, P32, 0) \
128 _(ANY, lj_strfmt_putfxint, 3, L, P32, XA_64) \
129 _(ANY, lj_strfmt_putfnum_int, 3, L, P32, XA_FP) \
130 _(ANY, lj_strfmt_putfnum_uint, 3, L, P32, XA_FP) \
131 _(ANY, lj_strfmt_putfnum, 3, L, P32, XA_FP) \
132 _(ANY, lj_strfmt_putfstr, 3, L, P32, 0) \
133 _(ANY, lj_strfmt_putfchar, 3, L, P32, 0) \
127 _(ANY, lj_buf_putmem, 3, S, P32, 0) \ 134 _(ANY, lj_buf_putmem, 3, S, P32, 0) \
128 _(ANY, lj_buf_putstr, 2, FL, P32, 0) \ 135 _(ANY, lj_buf_putstr, 2, FL, P32, 0) \
129 _(ANY, lj_buf_putchar, 2, FL, P32, 0) \ 136 _(ANY, lj_buf_putchar, 2, FL, P32, 0) \
diff --git a/src/lj_opt_fold.c b/src/lj_opt_fold.c
index e2ac28f2..f3abe8ea 100644
--- a/src/lj_opt_fold.c
+++ b/src/lj_opt_fold.c
@@ -617,6 +617,7 @@ LJFOLDF(bufstr_kfold_cse)
617LJFOLD(CALLL CARG IRCALL_lj_buf_putstr_reverse) 617LJFOLD(CALLL CARG IRCALL_lj_buf_putstr_reverse)
618LJFOLD(CALLL CARG IRCALL_lj_buf_putstr_upper) 618LJFOLD(CALLL CARG IRCALL_lj_buf_putstr_upper)
619LJFOLD(CALLL CARG IRCALL_lj_buf_putstr_lower) 619LJFOLD(CALLL CARG IRCALL_lj_buf_putstr_lower)
620LJFOLD(CALLL CARG IRCALL_lj_strfmt_putquoted)
620LJFOLDF(bufput_kfold_op) 621LJFOLDF(bufput_kfold_op)
621{ 622{
622 if (irref_isk(fleft->op2)) { 623 if (irref_isk(fleft->op2)) {
@@ -649,6 +650,48 @@ LJFOLDF(bufput_kfold_rep)
649 return EMITFOLD; /* Always emit, CSE later. */ 650 return EMITFOLD; /* Always emit, CSE later. */
650} 651}
651 652
653LJFOLD(CALLL CARG IRCALL_lj_strfmt_putfxint)
654LJFOLD(CALLL CARG IRCALL_lj_strfmt_putfnum_int)
655LJFOLD(CALLL CARG IRCALL_lj_strfmt_putfnum_uint)
656LJFOLD(CALLL CARG IRCALL_lj_strfmt_putfnum)
657LJFOLD(CALLL CARG IRCALL_lj_strfmt_putfstr)
658LJFOLD(CALLL CARG IRCALL_lj_strfmt_putfchar)
659LJFOLDF(bufput_kfold_fmt)
660{
661 IRIns *irc = IR(fleft->op1);
662 lua_assert(irref_isk(irc->op2)); /* SFormat must be const. */
663 if (irref_isk(fleft->op2)) {
664 SFormat sf = (SFormat)IR(irc->op2)->i;
665 IRIns *ira = IR(fleft->op2);
666 SBuf *sb = lj_buf_tmp_(J->L);
667 switch (fins->op2) {
668 case IRCALL_lj_strfmt_putfxint:
669 sb = lj_strfmt_putfxint(sb, sf, ir_k64(ira)->u64);
670 break;
671 case IRCALL_lj_strfmt_putfstr:
672 sb = lj_strfmt_putfstr(sb, sf, ir_kstr(ira));
673 break;
674 case IRCALL_lj_strfmt_putfchar:
675 sb = lj_strfmt_putfchar(sb, sf, ira->i);
676 break;
677 case IRCALL_lj_strfmt_putfnum_int:
678 case IRCALL_lj_strfmt_putfnum_uint:
679 case IRCALL_lj_strfmt_putfnum:
680 default: {
681 const CCallInfo *ci = &lj_ir_callinfo[fins->op2];
682 sb = ((SBuf * (*)(SBuf *, SFormat, lua_Number))ci->func)(sb, sf,
683 ir_knum(ira)->n);
684 break;
685 }
686 }
687 fins->o = IR_BUFPUT;
688 fins->op1 = irc->op1;
689 fins->op2 = lj_ir_kstr(J, lj_buf_tostr(sb));
690 return RETRYFOLD;
691 }
692 return EMITFOLD; /* Always emit, CSE later. */
693}
694
652/* -- Constant folding of pointer arithmetic ------------------------------ */ 695/* -- Constant folding of pointer arithmetic ------------------------------ */
653 696
654LJFOLD(ADD KGC KINT) 697LJFOLD(ADD KGC KINT)