From 39e53e8c4c4b6151c53e384d411ae48026e5567d Mon Sep 17 00:00:00 2001 From: Mike Pall Date: Tue, 23 Apr 2013 12:25:18 +0200 Subject: [PATCH] Compile string.char(). --- src/lib_string.c | 2 +- src/lj_ffrecord.c | 25 ++++++++++++++++++++++++- src/lj_opt_fold.c | 8 ++++++++ 3 files changed, 33 insertions(+), 2 deletions(-) diff --git a/src/lib_string.c b/src/lib_string.c index eb2ae226..27e0d594 100644 --- a/src/lib_string.c +++ b/src/lib_string.c @@ -62,7 +62,7 @@ LJLIB_ASM(string_byte) LJLIB_REC(string_range 0) return FFH_RES(n); } -LJLIB_ASM(string_char) +LJLIB_ASM(string_char) LJLIB_REC(.) { int i, nargs = (int)(L->top - L->base); char *buf = lj_buf_tmp(L, (size_t)nargs); diff --git a/src/lj_ffrecord.c b/src/lj_ffrecord.c index 929dbb55..191974ea 100644 --- a/src/lj_ffrecord.c +++ b/src/lj_ffrecord.c @@ -751,6 +751,26 @@ static void LJ_FASTCALL recff_string_range(jit_State *J, RecordFFData *rd) } } +static void LJ_FASTCALL recff_string_char(jit_State *J, RecordFFData *rd) +{ + TRef k255 = lj_ir_kint(J, 255); + BCReg i; + for (i = 0; J->base[i] != 0; i++) { /* Convert char values to strings. */ + TRef tr = lj_opt_narrow_toint(J, J->base[i]); + emitir(IRTGI(IR_ULE), tr, k255); + J->base[i] = emitir(IRT(IR_TOSTR, IRT_STR), tr, IRTOSTR_CHAR); + } + if (i > 1) { /* Concatenate the strings, if there's more than one. */ + TRef hdr = emitir(IRT(IR_BUFHDR, IRT_P32), + lj_ir_kptr(J, &J2G(J)->tmpbuf), IRBUFHDR_RESET); + TRef tr = hdr; + for (i = 0; J->base[i] != 0; i++) + tr = emitir(IRT(IR_BUFPUT, IRT_P32), tr, J->base[i]); + J->base[0] = emitir(IRT(IR_BUFSTR, IRT_STR), hdr, tr); + } + UNUSED(rd); +} + /* -- Table library fast functions ---------------------------------------- */ static void LJ_FASTCALL recff_table_insert(jit_State *J, RecordFFData *rd) @@ -809,7 +829,10 @@ static void LJ_FASTCALL recff_io_write(jit_State *J, RecordFFData *rd) TRef buf = emitir(IRT(IR_STRREF, IRT_P32), str, zero); TRef len = emitir(IRTI(IR_FLOAD), str, IRFL_STR_LEN); if (tref_isk(len) && IR(tref_ref(len))->i == 1) { - TRef tr = emitir(IRT(IR_XLOAD, IRT_U8), buf, IRXLOAD_READONLY); + IRIns *irs = IR(tref_ref(str)); + TRef tr = (irs->o == IR_TOSTR && irs->op2 == IRTOSTR_CHAR) ? + irs->op1 : + emitir(IRT(IR_XLOAD, IRT_U8), buf, IRXLOAD_READONLY); tr = lj_ir_call(J, IRCALL_fputc, tr, fp); if (results_wanted(J) != 0) /* Check result only if not ignored. */ emitir(IRTGI(IR_NE), tr, lj_ir_kint(J, -1)); diff --git a/src/lj_opt_fold.c b/src/lj_opt_fold.c index 06e0e783..75b8e174 100644 --- a/src/lj_opt_fold.c +++ b/src/lj_opt_fold.c @@ -2074,6 +2074,14 @@ LJFOLDF(fload_str_len_snew) return NEXTFOLD; } +LJFOLD(FLOAD TOSTR IRFL_STR_LEN) +LJFOLDF(fload_str_len_tostr) +{ + if (LJ_LIKELY(J->flags & JIT_F_OPT_FOLD) && fleft->op2 == IRTOSTR_CHAR) + return INTFOLD(1); + return NEXTFOLD; +} + /* The C type ID of cdata objects is immutable. */ LJFOLD(FLOAD KGC IRFL_CDATA_CTYPEID) LJFOLDF(fload_cdata_typeid_kgc)