mirror of
https://github.com/LuaJIT/LuaJIT.git
synced 2025-02-07 23:24:09 +00:00
Use explicit conversion type for IR_TOSTR. Add char conversion.
This commit is contained in:
parent
557391c3b7
commit
255326afb6
@ -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)
|
||||||
|
32
src/lj_asm.c
32
src/lj_asm.c
@ -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
|
||||||
|
@ -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 {
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -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). */
|
||||||
|
@ -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) \
|
||||||
|
@ -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)
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -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. */
|
||||||
|
@ -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
|
||||||
|
Loading…
Reference in New Issue
Block a user