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, ["FREF "] = vmdef.irfield,
["FPMATH"] = vmdef.irfpm, ["FPMATH"] = vmdef.irfpm,
["BUFHDR"] = { [0] = "RESET", "APPEND" }, ["BUFHDR"] = { [0] = "RESET", "APPEND" },
["TOSTR "] = { [0] = "INT", "NUM", "CHAR" },
} }
local function ctlsub(c) local function ctlsub(c)

View File

@ -1070,23 +1070,26 @@ static void asm_bufput(ASMState *as, IRIns *ir)
GCstr *s = ir_kstr(irs); GCstr *s = ir_kstr(irs);
if (s->len == 1) { /* Optimize put of single-char string constant. */ if (s->len == 1) { /* Optimize put of single-char string constant. */
kchar = strdata(s)[0]; kchar = strdata(s)[0];
ci = &lj_ir_callinfo[IRCALL_lj_buf_putchar];
args[1] = ASMREF_TMP1; /* int, truncated to char */ 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)) { } else if (mayfuse(as, ir->op2) && ra_noreg(irs->r)) {
if (irs->o == IR_TOSTR) { /* Fuse number to string conversions. */ if (irs->o == IR_TOSTR) { /* Fuse number to string conversions. */
if (LJ_SOFTFP ? (irs+1)->o == IR_HIOP : irt_isnum(IR(irs->op1)->t)) { if (irs->op2 == IRTOSTR_NUM) {
ci = &lj_ir_callinfo[IRCALL_lj_buf_putnum];
args[1] = ASMREF_TMP1; /* TValue * */ args[1] = ASMREF_TMP1; /* TValue * */
ci = &lj_ir_callinfo[IRCALL_lj_buf_putnum];
} else { } else {
lua_assert(irt_isinteger(IR(irs->op1)->t)); lua_assert(irt_isinteger(IR(irs->op1)->t));
ci = &lj_ir_callinfo[IRCALL_lj_buf_putint];
args[1] = irs->op1; /* int */ 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. */ } else if (irs->o == IR_SNEW) { /* Fuse string allocation. */
ci = &lj_ir_callinfo[IRCALL_lj_buf_putmem];
args[1] = irs->op1; /* const void * */ args[1] = irs->op1; /* const void * */
args[2] = irs->op2; /* MSize */ args[2] = irs->op2; /* MSize */
ci = &lj_ir_callinfo[IRCALL_lj_buf_putmem];
} }
} }
asm_setupresult(as, ir, ci); /* SBuf * */ 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) static void asm_tostr(ASMState *as, IRIns *ir)
{ {
const CCallInfo *ci;
IRRef args[2]; IRRef args[2];
args[0] = ASMREF_L; args[0] = ASMREF_L;
as->gcsteps++; as->gcsteps++;
if (irt_isnum(IR(ir->op1)->t) || (LJ_SOFTFP && (ir+1)->o == IR_HIOP)) { if (ir->op2 == IRTOSTR_NUM) {
const CCallInfo *ci = &lj_ir_callinfo[IRCALL_lj_str_fromnum];
args[1] = ASMREF_TMP1; /* const lua_Number * */ args[1] = ASMREF_TMP1; /* const lua_Number * */
asm_setupresult(as, ir, ci); /* GCstr * */ ci = &lj_ir_callinfo[IRCALL_lj_str_fromnum];
asm_gencall(as, ci, args);
asm_tvptr(as, ra_releasetmp(as, ASMREF_TMP1), ir->op1);
} else { } else {
const CCallInfo *ci = &lj_ir_callinfo[IRCALL_lj_str_fromint];
args[1] = ir->op1; /* int32_t k */ args[1] = ir->op1; /* int32_t k */
asm_setupresult(as, ir, ci); /* GCstr * */ if (ir->op2 == IRTOSTR_INT)
asm_gencall(as, ci, args); 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 #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]. */ /* Pass on result in J->base[0]. */
} else if (!recff_metacall(J, rd, MM_tostring)) { } else if (!recff_metacall(J, rd, MM_tostring)) {
if (tref_isnumber(tr)) { 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)) { } else if (tref_ispri(tr)) {
J->base[0] = lj_ir_kstr(J, strV(&J->fn->c.upvalue[tref_type(tr)])); J->base[0] = lj_ir_kstr(J, strV(&J->fn->c.upvalue[tref_type(tr)]));
} else { } else {

View File

@ -444,7 +444,8 @@ TRef LJ_FASTCALL lj_ir_tostr(jit_State *J, TRef tr)
if (!tref_isstr(tr)) { if (!tref_isstr(tr)) {
if (!tref_isnumber(tr)) if (!tref_isnumber(tr))
lj_trace_err(J, LJ_TRERR_BADTYPE); 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; return tr;
} }

View File

@ -133,7 +133,7 @@
/* Type conversions. */ \ /* Type conversions. */ \
_(CONV, NW, ref, lit) \ _(CONV, NW, ref, lit) \
_(TOBIT, N , ref, ref) \ _(TOBIT, N , ref, ref) \
_(TOSTR, N , ref, ___) \ _(TOSTR, N , ref, lit) \
_(STRTO, N , ref, ___) \ _(STRTO, N , ref, ___) \
\ \
/* Calls. */ \ /* Calls. */ \
@ -246,6 +246,11 @@ IRFLDEF(FLENUM)
#define IRCONV_INDEX (2<<IRCONV_CSH) /* Check + special backprop rules. */ #define IRCONV_INDEX (2<<IRCONV_CSH) /* Check + special backprop rules. */
#define IRCONV_CHECK (3<<IRCONV_CSH) /* Number checked for integerness. */ #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 operands --------------------------------------------------------- */
/* IR operand mode (2 bit). */ /* IR operand mode (2 bit). */

View File

@ -105,6 +105,7 @@ typedef struct CCallInfo {
_(ANY, lj_strscan_num, 2, FN, INT, 0) \ _(ANY, lj_strscan_num, 2, FN, INT, 0) \
_(ANY, lj_str_fromint, 2, FN, STR, CCI_L) \ _(ANY, lj_str_fromint, 2, FN, STR, CCI_L) \
_(ANY, lj_str_fromnum, 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_putmem, 3, S, P32, 0) \
_(ANY, lj_buf_putstr, 2, FS, P32, 0) \ _(ANY, lj_buf_putstr, 2, FS, P32, 0) \
_(ANY, lj_buf_putchar, 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)); return INT64FOLD(lj_num2u64(knumleft));
} }
LJFOLD(TOSTR KNUM) LJFOLD(TOSTR KNUM any)
LJFOLDF(kfold_tostr_knum) LJFOLDF(kfold_tostr_knum)
{ {
return lj_ir_kstr(J, lj_str_fromnum(J->L, &knumleft)); return lj_ir_kstr(J, lj_str_fromnum(J->L, &knumleft));
} }
LJFOLD(TOSTR KINT) LJFOLD(TOSTR KINT any)
LJFOLDF(kfold_tostr_kint) 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) 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. */ /* First convert numbers to strings. */
for (trp = top; trp >= base; trp--) { for (trp = top; trp >= base; trp--) {
if (tref_isnumber(*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)) else if (!tref_isstr(*trp))
break; 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); 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 --------------------------------------------------- */ /* -- String formatting --------------------------------------------------- */
/* Push formatted message as a string object to Lua stack. va_list variant. */ /* 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_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_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_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_INTBUF (1+10)
#define LJ_STR_NUMBUF LUAI_MAXNUMBER2STR #define LJ_STR_NUMBUF LUAI_MAXNUMBER2STR