diff options
| author | Mike Pall <mike> | 2013-04-23 02:20:03 +0200 |
|---|---|---|
| committer | Mike Pall <mike> | 2013-04-23 02:20:03 +0200 |
| commit | 255326afb6fd428d62cf66e4e90a459b917a76a1 (patch) | |
| tree | 6fa5e70d1baa3df57f1e976fbc07f2c47174ee13 | |
| parent | 557391c3b7110cdb431a26351e87010e7f1a41e9 (diff) | |
| download | luajit-255326afb6fd428d62cf66e4e90a459b917a76a1.tar.gz luajit-255326afb6fd428d62cf66e4e90a459b917a76a1.tar.bz2 luajit-255326afb6fd428d62cf66e4e90a459b917a76a1.zip | |
Use explicit conversion type for IR_TOSTR. Add char conversion.
| -rw-r--r-- | src/jit/dump.lua | 1 | ||||
| -rw-r--r-- | src/lj_asm.c | 32 | ||||
| -rw-r--r-- | src/lj_ffrecord.c | 3 | ||||
| -rw-r--r-- | src/lj_ir.c | 3 | ||||
| -rw-r--r-- | src/lj_ir.h | 7 | ||||
| -rw-r--r-- | src/lj_ircall.h | 1 | ||||
| -rw-r--r-- | src/lj_opt_fold.c | 8 | ||||
| -rw-r--r-- | src/lj_record.c | 3 | ||||
| -rw-r--r-- | src/lj_str.c | 8 | ||||
| -rw-r--r-- | 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 = { | |||
| 279 | ["FREF "] = vmdef.irfield, | 279 | ["FREF "] = vmdef.irfield, |
| 280 | ["FPMATH"] = vmdef.irfpm, | 280 | ["FPMATH"] = vmdef.irfpm, |
| 281 | ["BUFHDR"] = { [0] = "RESET", "APPEND" }, | 281 | ["BUFHDR"] = { [0] = "RESET", "APPEND" }, |
| 282 | ["TOSTR "] = { [0] = "INT", "NUM", "CHAR" }, | ||
| 282 | } | 283 | } |
| 283 | 284 | ||
| 284 | local function ctlsub(c) | 285 | 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) | |||
| 1070 | GCstr *s = ir_kstr(irs); | 1070 | GCstr *s = ir_kstr(irs); |
| 1071 | if (s->len == 1) { /* Optimize put of single-char string constant. */ | 1071 | if (s->len == 1) { /* Optimize put of single-char string constant. */ |
| 1072 | kchar = strdata(s)[0]; | 1072 | kchar = strdata(s)[0]; |
| 1073 | ci = &lj_ir_callinfo[IRCALL_lj_buf_putchar]; | ||
| 1074 | args[1] = ASMREF_TMP1; /* int, truncated to char */ | 1073 | args[1] = ASMREF_TMP1; /* int, truncated to char */ |
| 1074 | ci = &lj_ir_callinfo[IRCALL_lj_buf_putchar]; | ||
| 1075 | } | 1075 | } |
| 1076 | } else if (mayfuse(as, ir->op2) && ra_noreg(irs->r)) { | 1076 | } else if (mayfuse(as, ir->op2) && ra_noreg(irs->r)) { |
| 1077 | if (irs->o == IR_TOSTR) { /* Fuse number to string conversions. */ | 1077 | if (irs->o == IR_TOSTR) { /* Fuse number to string conversions. */ |
| 1078 | if (LJ_SOFTFP ? (irs+1)->o == IR_HIOP : irt_isnum(IR(irs->op1)->t)) { | 1078 | if (irs->op2 == IRTOSTR_NUM) { |
| 1079 | ci = &lj_ir_callinfo[IRCALL_lj_buf_putnum]; | ||
| 1080 | args[1] = ASMREF_TMP1; /* TValue * */ | 1079 | args[1] = ASMREF_TMP1; /* TValue * */ |
| 1080 | ci = &lj_ir_callinfo[IRCALL_lj_buf_putnum]; | ||
| 1081 | } else { | 1081 | } else { |
| 1082 | lua_assert(irt_isinteger(IR(irs->op1)->t)); | 1082 | lua_assert(irt_isinteger(IR(irs->op1)->t)); |
| 1083 | ci = &lj_ir_callinfo[IRCALL_lj_buf_putint]; | ||
| 1084 | args[1] = irs->op1; /* int */ | 1083 | args[1] = irs->op1; /* int */ |
| 1084 | if (irs->op2 == IRTOSTR_INT) | ||
| 1085 | ci = &lj_ir_callinfo[IRCALL_lj_buf_putint]; | ||
| 1086 | else | ||
| 1087 | ci = &lj_ir_callinfo[IRCALL_lj_buf_putchar]; | ||
| 1085 | } | 1088 | } |
| 1086 | } else if (irs->o == IR_SNEW) { /* Fuse string allocation. */ | 1089 | } else if (irs->o == IR_SNEW) { /* Fuse string allocation. */ |
| 1087 | ci = &lj_ir_callinfo[IRCALL_lj_buf_putmem]; | ||
| 1088 | args[1] = irs->op1; /* const void * */ | 1090 | args[1] = irs->op1; /* const void * */ |
| 1089 | args[2] = irs->op2; /* MSize */ | 1091 | args[2] = irs->op2; /* MSize */ |
| 1092 | ci = &lj_ir_callinfo[IRCALL_lj_buf_putmem]; | ||
| 1090 | } | 1093 | } |
| 1091 | } | 1094 | } |
| 1092 | asm_setupresult(as, ir, ci); /* SBuf * */ | 1095 | asm_setupresult(as, ir, ci); /* SBuf * */ |
| @@ -1114,21 +1117,24 @@ static void asm_bufstr(ASMState *as, IRIns *ir) | |||
| 1114 | 1117 | ||
| 1115 | static void asm_tostr(ASMState *as, IRIns *ir) | 1118 | static void asm_tostr(ASMState *as, IRIns *ir) |
| 1116 | { | 1119 | { |
| 1120 | const CCallInfo *ci; | ||
| 1117 | IRRef args[2]; | 1121 | IRRef args[2]; |
| 1118 | args[0] = ASMREF_L; | 1122 | args[0] = ASMREF_L; |
| 1119 | as->gcsteps++; | 1123 | as->gcsteps++; |
| 1120 | if (irt_isnum(IR(ir->op1)->t) || (LJ_SOFTFP && (ir+1)->o == IR_HIOP)) { | 1124 | if (ir->op2 == IRTOSTR_NUM) { |
| 1121 | const CCallInfo *ci = &lj_ir_callinfo[IRCALL_lj_str_fromnum]; | ||
| 1122 | args[1] = ASMREF_TMP1; /* const lua_Number * */ | 1125 | args[1] = ASMREF_TMP1; /* const lua_Number * */ |
| 1123 | asm_setupresult(as, ir, ci); /* GCstr * */ | 1126 | ci = &lj_ir_callinfo[IRCALL_lj_str_fromnum]; |
| 1124 | asm_gencall(as, ci, args); | ||
| 1125 | asm_tvptr(as, ra_releasetmp(as, ASMREF_TMP1), ir->op1); | ||
| 1126 | } else { | 1127 | } else { |
| 1127 | const CCallInfo *ci = &lj_ir_callinfo[IRCALL_lj_str_fromint]; | ||
| 1128 | args[1] = ir->op1; /* int32_t k */ | 1128 | args[1] = ir->op1; /* int32_t k */ |
| 1129 | asm_setupresult(as, ir, ci); /* GCstr * */ | 1129 | if (ir->op2 == IRTOSTR_INT) |
| 1130 | asm_gencall(as, ci, args); | 1130 | ci = &lj_ir_callinfo[IRCALL_lj_str_fromint]; |
| 1131 | else | ||
| 1132 | ci = &lj_ir_callinfo[IRCALL_lj_str_fromchar]; | ||
| 1131 | } | 1133 | } |
| 1134 | asm_setupresult(as, ir, ci); /* GCstr * */ | ||
| 1135 | asm_gencall(as, ci, args); | ||
| 1136 | if (ir->op2 == IRTOSTR_NUM) | ||
| 1137 | asm_tvptr(as, ra_releasetmp(as, ASMREF_TMP1), ir->op1); | ||
| 1132 | } | 1138 | } |
| 1133 | 1139 | ||
| 1134 | #if LJ_32 && LJ_HASFFI && !LJ_SOFTFP && !LJ_TARGET_X86 | 1140 | #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) | |||
| 335 | /* Pass on result in J->base[0]. */ | 335 | /* Pass on result in J->base[0]. */ |
| 336 | } else if (!recff_metacall(J, rd, MM_tostring)) { | 336 | } else if (!recff_metacall(J, rd, MM_tostring)) { |
| 337 | if (tref_isnumber(tr)) { | 337 | if (tref_isnumber(tr)) { |
| 338 | J->base[0] = emitir(IRT(IR_TOSTR, IRT_STR), tr, 0); | 338 | J->base[0] = emitir(IRT(IR_TOSTR, IRT_STR), tr, |
| 339 | tref_isnum(tr) ? IRTOSTR_NUM : IRTOSTR_INT); | ||
| 339 | } else if (tref_ispri(tr)) { | 340 | } else if (tref_ispri(tr)) { |
| 340 | J->base[0] = lj_ir_kstr(J, strV(&J->fn->c.upvalue[tref_type(tr)])); | 341 | J->base[0] = lj_ir_kstr(J, strV(&J->fn->c.upvalue[tref_type(tr)])); |
| 341 | } else { | 342 | } 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) | |||
| 444 | if (!tref_isstr(tr)) { | 444 | if (!tref_isstr(tr)) { |
| 445 | if (!tref_isnumber(tr)) | 445 | if (!tref_isnumber(tr)) |
| 446 | lj_trace_err(J, LJ_TRERR_BADTYPE); | 446 | lj_trace_err(J, LJ_TRERR_BADTYPE); |
| 447 | tr = emitir(IRT(IR_TOSTR, IRT_STR), tr, 0); | 447 | tr = emitir(IRT(IR_TOSTR, IRT_STR), tr, |
| 448 | tref_isnum(tr) ? IRTOSTR_NUM : IRTOSTR_INT); | ||
| 448 | } | 449 | } |
| 449 | return tr; | 450 | return tr; |
| 450 | } | 451 | } |
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 @@ | |||
| 133 | /* Type conversions. */ \ | 133 | /* Type conversions. */ \ |
| 134 | _(CONV, NW, ref, lit) \ | 134 | _(CONV, NW, ref, lit) \ |
| 135 | _(TOBIT, N , ref, ref) \ | 135 | _(TOBIT, N , ref, ref) \ |
| 136 | _(TOSTR, N , ref, ___) \ | 136 | _(TOSTR, N , ref, lit) \ |
| 137 | _(STRTO, N , ref, ___) \ | 137 | _(STRTO, N , ref, ___) \ |
| 138 | \ | 138 | \ |
| 139 | /* Calls. */ \ | 139 | /* Calls. */ \ |
| @@ -246,6 +246,11 @@ IRFLDEF(FLENUM) | |||
| 246 | #define IRCONV_INDEX (2<<IRCONV_CSH) /* Check + special backprop rules. */ | 246 | #define IRCONV_INDEX (2<<IRCONV_CSH) /* Check + special backprop rules. */ |
| 247 | #define IRCONV_CHECK (3<<IRCONV_CSH) /* Number checked for integerness. */ | 247 | #define IRCONV_CHECK (3<<IRCONV_CSH) /* Number checked for integerness. */ |
| 248 | 248 | ||
| 249 | /* TOSTR mode, stored in op2. */ | ||
| 250 | #define IRTOSTR_INT 0 /* Convert integer to string. */ | ||
| 251 | #define IRTOSTR_NUM 1 /* Convert number to string. */ | ||
| 252 | #define IRTOSTR_CHAR 2 /* Convert char value to string. */ | ||
| 253 | |||
| 249 | /* -- IR operands --------------------------------------------------------- */ | 254 | /* -- IR operands --------------------------------------------------------- */ |
| 250 | 255 | ||
| 251 | /* IR operand mode (2 bit). */ | 256 | /* IR operand mode (2 bit). */ |
diff --git a/src/lj_ircall.h b/src/lj_ircall.h index 46bb54fe..456f89ac 100644 --- a/src/lj_ircall.h +++ b/src/lj_ircall.h | |||
| @@ -105,6 +105,7 @@ typedef struct CCallInfo { | |||
| 105 | _(ANY, lj_strscan_num, 2, FN, INT, 0) \ | 105 | _(ANY, lj_strscan_num, 2, FN, INT, 0) \ |
| 106 | _(ANY, lj_str_fromint, 2, FN, STR, CCI_L) \ | 106 | _(ANY, lj_str_fromint, 2, FN, STR, CCI_L) \ |
| 107 | _(ANY, lj_str_fromnum, 2, FN, STR, CCI_L) \ | 107 | _(ANY, lj_str_fromnum, 2, FN, STR, CCI_L) \ |
| 108 | _(ANY, lj_str_fromchar, 2, FN, STR, CCI_L) \ | ||
| 108 | _(ANY, lj_buf_putmem, 3, S, P32, 0) \ | 109 | _(ANY, lj_buf_putmem, 3, S, P32, 0) \ |
| 109 | _(ANY, lj_buf_putstr, 2, FS, P32, 0) \ | 110 | _(ANY, lj_buf_putstr, 2, FS, P32, 0) \ |
| 110 | _(ANY, lj_buf_putchar, 2, FS, P32, 0) \ | 111 | _(ANY, lj_buf_putchar, 2, FS, P32, 0) \ |
diff --git a/src/lj_opt_fold.c b/src/lj_opt_fold.c index e3194f76..06e0e783 100644 --- a/src/lj_opt_fold.c +++ b/src/lj_opt_fold.c | |||
| @@ -759,16 +759,18 @@ LJFOLDF(kfold_conv_knum_u64_num) | |||
| 759 | return INT64FOLD(lj_num2u64(knumleft)); | 759 | return INT64FOLD(lj_num2u64(knumleft)); |
| 760 | } | 760 | } |
| 761 | 761 | ||
| 762 | LJFOLD(TOSTR KNUM) | 762 | LJFOLD(TOSTR KNUM any) |
| 763 | LJFOLDF(kfold_tostr_knum) | 763 | LJFOLDF(kfold_tostr_knum) |
| 764 | { | 764 | { |
| 765 | return lj_ir_kstr(J, lj_str_fromnum(J->L, &knumleft)); | 765 | return lj_ir_kstr(J, lj_str_fromnum(J->L, &knumleft)); |
| 766 | } | 766 | } |
| 767 | 767 | ||
| 768 | LJFOLD(TOSTR KINT) | 768 | LJFOLD(TOSTR KINT any) |
| 769 | LJFOLDF(kfold_tostr_kint) | 769 | LJFOLDF(kfold_tostr_kint) |
| 770 | { | 770 | { |
| 771 | return lj_ir_kstr(J, lj_str_fromint(J->L, fleft->i)); | 771 | return lj_ir_kstr(J, fins->op2 == IRTOSTR_INT ? |
| 772 | lj_str_fromint(J->L, fleft->i) : | ||
| 773 | lj_str_fromchar(J->L, fleft->i)); | ||
| 772 | } | 774 | } |
| 773 | 775 | ||
| 774 | LJFOLD(STRTO KGC) | 776 | 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) | |||
| 1611 | /* First convert numbers to strings. */ | 1611 | /* First convert numbers to strings. */ |
| 1612 | for (trp = top; trp >= base; trp--) { | 1612 | for (trp = top; trp >= base; trp--) { |
| 1613 | if (tref_isnumber(*trp)) | 1613 | if (tref_isnumber(*trp)) |
| 1614 | *trp = emitir(IRT(IR_TOSTR, IRT_STR), *trp, 0); | 1614 | *trp = emitir(IRT(IR_TOSTR, IRT_STR), *trp, |
| 1615 | tref_isnum(*trp) ? IRTOSTR_NUM : IRTOSTR_INT); | ||
| 1615 | else if (!tref_isstr(*trp)) | 1616 | else if (!tref_isstr(*trp)) |
| 1616 | break; | 1617 | break; |
| 1617 | } | 1618 | } |
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) | |||
| 274 | return tvisint(o) ? lj_str_fromint(L, intV(o)) : lj_str_fromnum(L, &o->n); | 274 | return tvisint(o) ? lj_str_fromint(L, intV(o)) : lj_str_fromnum(L, &o->n); |
| 275 | } | 275 | } |
| 276 | 276 | ||
| 277 | /* Convert char value to string. */ | ||
| 278 | GCstr * LJ_FASTCALL lj_str_fromchar(lua_State *L, int c) | ||
| 279 | { | ||
| 280 | char buf[1]; | ||
| 281 | buf[0] = c; | ||
| 282 | return lj_str_new(L, buf, 1); | ||
| 283 | } | ||
| 284 | |||
| 277 | /* -- String formatting --------------------------------------------------- */ | 285 | /* -- String formatting --------------------------------------------------- */ |
| 278 | 286 | ||
| 279 | /* Push formatted message as a string object to Lua stack. va_list variant. */ | 287 | /* 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); | |||
| 27 | LJ_FUNCA GCstr * LJ_FASTCALL lj_str_fromnum(lua_State *L, const lua_Number *np); | 27 | LJ_FUNCA GCstr * LJ_FASTCALL lj_str_fromnum(lua_State *L, const lua_Number *np); |
| 28 | LJ_FUNC GCstr * LJ_FASTCALL lj_str_fromint(lua_State *L, int32_t k); | 28 | LJ_FUNC GCstr * LJ_FASTCALL lj_str_fromint(lua_State *L, int32_t k); |
| 29 | LJ_FUNCA GCstr * LJ_FASTCALL lj_str_fromnumber(lua_State *L, cTValue *o); | 29 | LJ_FUNCA GCstr * LJ_FASTCALL lj_str_fromnumber(lua_State *L, cTValue *o); |
| 30 | LJ_FUNC GCstr * LJ_FASTCALL lj_str_fromchar(lua_State *L, int c); | ||
| 30 | 31 | ||
| 31 | #define LJ_STR_INTBUF (1+10) | 32 | #define LJ_STR_INTBUF (1+10) |
| 32 | #define LJ_STR_NUMBUF LUAI_MAXNUMBER2STR | 33 | #define LJ_STR_NUMBUF LUAI_MAXNUMBER2STR |
