Use explicit conversion type for IR_TOSTR. Add char conversion.

This commit is contained in:
Mike Pall 2013-04-23 02:20:03 +02:00
parent 557391c3b7
commit 255326afb6
10 changed files with 47 additions and 20 deletions

View File

@ -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)

View File

@ -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

View File

@ -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 {

View File

@ -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;
}

View File

@ -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<<IRCONV_CSH) /* Check + special backprop rules. */
#define IRCONV_CHECK (3<<IRCONV_CSH) /* Number checked for integerness. */
/* TOSTR mode, stored in op2. */
#define IRTOSTR_INT 0 /* Convert integer to string. */
#define IRTOSTR_NUM 1 /* Convert number to string. */
#define IRTOSTR_CHAR 2 /* Convert char value to string. */
/* -- IR operands --------------------------------------------------------- */
/* IR operand mode (2 bit). */

View File

@ -105,6 +105,7 @@ typedef struct CCallInfo {
_(ANY, lj_strscan_num, 2, FN, INT, 0) \
_(ANY, lj_str_fromint, 2, FN, STR, CCI_L) \
_(ANY, lj_str_fromnum, 2, FN, STR, CCI_L) \
_(ANY, lj_str_fromchar, 2, FN, STR, CCI_L) \
_(ANY, lj_buf_putmem, 3, S, P32, 0) \
_(ANY, lj_buf_putstr, 2, FS, P32, 0) \
_(ANY, lj_buf_putchar, 2, FS, P32, 0) \

View File

@ -759,16 +759,18 @@ LJFOLDF(kfold_conv_knum_u64_num)
return INT64FOLD(lj_num2u64(knumleft));
}
LJFOLD(TOSTR KNUM)
LJFOLD(TOSTR KNUM any)
LJFOLDF(kfold_tostr_knum)
{
return lj_ir_kstr(J, lj_str_fromnum(J->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)

View File

@ -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;
}

View File

@ -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. */

View File

@ -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