aboutsummaryrefslogtreecommitdiff
path: root/src/lj_ffrecord.c
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/lj_ffrecord.c78
1 files changed, 78 insertions, 0 deletions
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)