From 255326afb6fd428d62cf66e4e90a459b917a76a1 Mon Sep 17 00:00:00 2001 From: Mike Pall Date: Tue, 23 Apr 2013 02:20:03 +0200 Subject: [PATCH] Use explicit conversion type for IR_TOSTR. Add char conversion. --- src/jit/dump.lua | 1 + src/lj_asm.c | 32 +++++++++++++++++++------------- src/lj_ffrecord.c | 3 ++- src/lj_ir.c | 3 ++- src/lj_ir.h | 7 ++++++- src/lj_ircall.h | 1 + src/lj_opt_fold.c | 8 +++++--- src/lj_record.c | 3 ++- src/lj_str.c | 8 ++++++++ src/lj_str.h | 1 + 10 files changed, 47 insertions(+), 20 deletions(-) diff --git a/src/jit/dump.lua b/src/jit/dump.lua index c025a239..2a7d64e4 100644 --- a/src/jit/dump.lua +++ b/src/jit/dump.lua @@ -279,6 +279,7 @@ local litname = { ["FREF "] = vmdef.irfield, ["FPMATH"] = vmdef.irfpm, ["BUFHDR"] = { [0] = "RESET", "APPEND" }, + ["TOSTR "] = { [0] = "INT", "NUM", "CHAR" }, } local function ctlsub(c) diff --git a/src/lj_asm.c b/src/lj_asm.c index e847b8c9..6ff32940 100644 --- a/src/lj_asm.c +++ b/src/lj_asm.c @@ -1070,23 +1070,26 @@ static void asm_bufput(ASMState *as, IRIns *ir) GCstr *s = ir_kstr(irs); if (s->len == 1) { /* Optimize put of single-char string constant. */ kchar = strdata(s)[0]; - ci = &lj_ir_callinfo[IRCALL_lj_buf_putchar]; args[1] = ASMREF_TMP1; /* int, truncated to char */ + ci = &lj_ir_callinfo[IRCALL_lj_buf_putchar]; } } else if (mayfuse(as, ir->op2) && ra_noreg(irs->r)) { if (irs->o == IR_TOSTR) { /* Fuse number to string conversions. */ - if (LJ_SOFTFP ? (irs+1)->o == IR_HIOP : irt_isnum(IR(irs->op1)->t)) { - ci = &lj_ir_callinfo[IRCALL_lj_buf_putnum]; + if (irs->op2 == IRTOSTR_NUM) { args[1] = ASMREF_TMP1; /* TValue * */ + ci = &lj_ir_callinfo[IRCALL_lj_buf_putnum]; } else { lua_assert(irt_isinteger(IR(irs->op1)->t)); - ci = &lj_ir_callinfo[IRCALL_lj_buf_putint]; args[1] = irs->op1; /* int */ + if (irs->op2 == IRTOSTR_INT) + ci = &lj_ir_callinfo[IRCALL_lj_buf_putint]; + else + ci = &lj_ir_callinfo[IRCALL_lj_buf_putchar]; } } else if (irs->o == IR_SNEW) { /* Fuse string allocation. */ - ci = &lj_ir_callinfo[IRCALL_lj_buf_putmem]; args[1] = irs->op1; /* const void * */ args[2] = irs->op2; /* MSize */ + ci = &lj_ir_callinfo[IRCALL_lj_buf_putmem]; } } asm_setupresult(as, ir, ci); /* SBuf * */ @@ -1114,21 +1117,24 @@ static void asm_bufstr(ASMState *as, IRIns *ir) static void asm_tostr(ASMState *as, IRIns *ir) { + const CCallInfo *ci; IRRef args[2]; args[0] = ASMREF_L; as->gcsteps++; - if (irt_isnum(IR(ir->op1)->t) || (LJ_SOFTFP && (ir+1)->o == IR_HIOP)) { - const CCallInfo *ci = &lj_ir_callinfo[IRCALL_lj_str_fromnum]; + if (ir->op2 == IRTOSTR_NUM) { args[1] = ASMREF_TMP1; /* const lua_Number * */ - asm_setupresult(as, ir, ci); /* GCstr * */ - asm_gencall(as, ci, args); - asm_tvptr(as, ra_releasetmp(as, ASMREF_TMP1), ir->op1); + ci = &lj_ir_callinfo[IRCALL_lj_str_fromnum]; } else { - const CCallInfo *ci = &lj_ir_callinfo[IRCALL_lj_str_fromint]; args[1] = ir->op1; /* int32_t k */ - asm_setupresult(as, ir, ci); /* GCstr * */ - asm_gencall(as, ci, args); + if (ir->op2 == IRTOSTR_INT) + ci = &lj_ir_callinfo[IRCALL_lj_str_fromint]; + else + ci = &lj_ir_callinfo[IRCALL_lj_str_fromchar]; } + asm_setupresult(as, ir, ci); /* GCstr * */ + asm_gencall(as, ci, args); + if (ir->op2 == IRTOSTR_NUM) + asm_tvptr(as, ra_releasetmp(as, ASMREF_TMP1), ir->op1); } #if LJ_32 && LJ_HASFFI && !LJ_SOFTFP && !LJ_TARGET_X86 diff --git a/src/lj_ffrecord.c b/src/lj_ffrecord.c index 32346d22..929dbb55 100644 --- a/src/lj_ffrecord.c +++ b/src/lj_ffrecord.c @@ -335,7 +335,8 @@ static void LJ_FASTCALL recff_tostring(jit_State *J, RecordFFData *rd) /* Pass on result in J->base[0]. */ } else if (!recff_metacall(J, rd, MM_tostring)) { if (tref_isnumber(tr)) { - J->base[0] = emitir(IRT(IR_TOSTR, IRT_STR), tr, 0); + J->base[0] = emitir(IRT(IR_TOSTR, IRT_STR), tr, + tref_isnum(tr) ? IRTOSTR_NUM : IRTOSTR_INT); } else if (tref_ispri(tr)) { J->base[0] = lj_ir_kstr(J, strV(&J->fn->c.upvalue[tref_type(tr)])); } else { diff --git a/src/lj_ir.c b/src/lj_ir.c index f1e1959f..0ac9d0e6 100644 --- a/src/lj_ir.c +++ b/src/lj_ir.c @@ -444,7 +444,8 @@ TRef LJ_FASTCALL lj_ir_tostr(jit_State *J, TRef tr) if (!tref_isstr(tr)) { if (!tref_isnumber(tr)) lj_trace_err(J, LJ_TRERR_BADTYPE); - tr = emitir(IRT(IR_TOSTR, IRT_STR), tr, 0); + tr = emitir(IRT(IR_TOSTR, IRT_STR), tr, + tref_isnum(tr) ? IRTOSTR_NUM : IRTOSTR_INT); } return tr; } diff --git a/src/lj_ir.h b/src/lj_ir.h index 0cbd8b55..7ab8ab12 100644 --- a/src/lj_ir.h +++ b/src/lj_ir.h @@ -133,7 +133,7 @@ /* Type conversions. */ \ _(CONV, NW, ref, lit) \ _(TOBIT, N , ref, ref) \ - _(TOSTR, N , ref, ___) \ + _(TOSTR, N , ref, lit) \ _(STRTO, N , ref, ___) \ \ /* Calls. */ \ @@ -246,6 +246,11 @@ IRFLDEF(FLENUM) #define IRCONV_INDEX (2<L, &knumleft)); } -LJFOLD(TOSTR KINT) +LJFOLD(TOSTR KINT any) LJFOLDF(kfold_tostr_kint) { - return lj_ir_kstr(J, lj_str_fromint(J->L, fleft->i)); + return lj_ir_kstr(J, fins->op2 == IRTOSTR_INT ? + lj_str_fromint(J->L, fleft->i) : + lj_str_fromchar(J->L, fleft->i)); } LJFOLD(STRTO KGC) diff --git a/src/lj_record.c b/src/lj_record.c index bafb6ff7..1beaa75f 100644 --- a/src/lj_record.c +++ b/src/lj_record.c @@ -1611,7 +1611,8 @@ static TRef rec_cat(jit_State *J, BCReg baseslot, BCReg topslot) /* First convert numbers to strings. */ for (trp = top; trp >= base; trp--) { if (tref_isnumber(*trp)) - *trp = emitir(IRT(IR_TOSTR, IRT_STR), *trp, 0); + *trp = emitir(IRT(IR_TOSTR, IRT_STR), *trp, + tref_isnum(*trp) ? IRTOSTR_NUM : IRTOSTR_INT); else if (!tref_isstr(*trp)) break; } diff --git a/src/lj_str.c b/src/lj_str.c index a0080e31..675213d7 100644 --- a/src/lj_str.c +++ b/src/lj_str.c @@ -274,6 +274,14 @@ GCstr * LJ_FASTCALL lj_str_fromnumber(lua_State *L, cTValue *o) return tvisint(o) ? lj_str_fromint(L, intV(o)) : lj_str_fromnum(L, &o->n); } +/* Convert char value to string. */ +GCstr * LJ_FASTCALL lj_str_fromchar(lua_State *L, int c) +{ + char buf[1]; + buf[0] = c; + return lj_str_new(L, buf, 1); +} + /* -- String formatting --------------------------------------------------- */ /* Push formatted message as a string object to Lua stack. va_list variant. */ diff --git a/src/lj_str.h b/src/lj_str.h index 61666a2a..bf508d3b 100644 --- a/src/lj_str.h +++ b/src/lj_str.h @@ -27,6 +27,7 @@ LJ_FUNC const char *lj_str_buftv(char *buf, cTValue *o, MSize *lenp); LJ_FUNCA GCstr * LJ_FASTCALL lj_str_fromnum(lua_State *L, const lua_Number *np); LJ_FUNC GCstr * LJ_FASTCALL lj_str_fromint(lua_State *L, int32_t k); LJ_FUNCA GCstr * LJ_FASTCALL lj_str_fromnumber(lua_State *L, cTValue *o); +LJ_FUNC GCstr * LJ_FASTCALL lj_str_fromchar(lua_State *L, int c); #define LJ_STR_INTBUF (1+10) #define LJ_STR_NUMBUF LUAI_MAXNUMBER2STR