]> git.ipfire.org Git - thirdparty/LuaJIT.git/commitdiff
Use explicit conversion type for IR_TOSTR. Add char conversion.
authorMike Pall <mike>
Tue, 23 Apr 2013 00:20:03 +0000 (02:20 +0200)
committerMike Pall <mike>
Tue, 23 Apr 2013 00:20:03 +0000 (02:20 +0200)
src/jit/dump.lua
src/lj_asm.c
src/lj_ffrecord.c
src/lj_ir.c
src/lj_ir.h
src/lj_ircall.h
src/lj_opt_fold.c
src/lj_record.c
src/lj_str.c
src/lj_str.h

index c025a239347345144e16cf733e907fd435b3fe6d..2a7d64e4edc636a97ddc024f955177c5c0120559 100644 (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)
index e847b8c946206128f1530ec8a961950968354ded..6ff3294013c14de4c81173b005603a4f61886490 100644 (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
index 32346d229410c11c05982354a943c05dd79f785c..929dbb554f6532fed8151bdfda876ce9a49ddbd3 100644 (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 {
index f1e1959f047875b07197134337a791156af341a7..0ac9d0e66cdfd4ed79425b761d627614c79e1b4f 100644 (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;
 }
index 0cbd8b55834937e43f5c6f2d76490906854d3298..7ab8ab128684edcb04e46cf7566aa1a663efb099 100644 (file)
   /* 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). */
index 46bb54fefa511d069acc350133a4904d68997e09..456f89ac58cc7e189580c9715c11bd0fd9cd5f09 100644 (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) \
index e3194f7633d44bf11457a61070780870a0bbb268..06e0e78353c9cd66e1ac9e4dba5599a31dfd4684 100644 (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)
index bafb6ff70323c94111a394701cba071be414a62d..1beaa75fbdaedd60d2b910807f45c8ae72b65735 100644 (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;
     }
index a0080e31bfb2f06f0e76aeb821fd913ca7e1a813..675213d71df3095b0cd0c0e04330fe03bc060b91 100644 (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. */
index 61666a2a588bf6affa99e5cefc88fc2380f46c64..bf508d3bddcf1a00ba9cbab66879ff8a136c71ba 100644 (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