diff --git a/src/Makefile.dep b/src/Makefile.dep index e9f83399..7b534b05 100644 --- a/src/Makefile.dep +++ b/src/Makefile.dep @@ -98,7 +98,7 @@ lj_crecord.o: lj_crecord.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \ lj_cdata.h lj_cparse.h lj_cconv.h lj_carith.h lj_clib.h lj_ccall.h \ lj_ff.h lj_ffdef.h lj_ir.h lj_jit.h lj_ircall.h lj_iropt.h lj_trace.h \ lj_dispatch.h lj_traceerr.h lj_record.h lj_ffrecord.h lj_snap.h \ - lj_crecord.h lj_strfmt.h + lj_crecord.h lj_strfmt.h lj_strscan.h lj_ctype.o: lj_ctype.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \ lj_gc.h lj_err.h lj_errmsg.h lj_str.h lj_tab.h lj_strfmt.h lj_ctype.h \ lj_ccallback.h lj_buf.h diff --git a/src/lj_crecord.c b/src/lj_crecord.c index 79159454..e8ae426d 100644 --- a/src/lj_crecord.c +++ b/src/lj_crecord.c @@ -32,6 +32,7 @@ #include "lj_crecord.h" #include "lj_dispatch.h" #include "lj_strfmt.h" +#include "lj_strscan.h" /* Some local macros to save typing. Undef'd at the end. */ #define IR(ref) (&J->cur.ir[(ref)]) @@ -1807,11 +1808,21 @@ static CTypeID crec_bit64_type(CTState *cts, cTValue *tv) return 0; /* Use regular 32 bit ops. */ } +static TRef crec_bit64_arg(jit_State *J, CType *d, TRef sp, TValue *sval) +{ + if (LJ_UNLIKELY(tref_isstr(sp))) { + if (lj_strscan_num(strV(sval), sval)) { + sp = emitir(IRTG(IR_STRTO, IRT_NUM), sp, 0); + } /* else: interpreter will throw. */ + } + return crec_ct_tv(J, d, 0, sp, sval); +} + void LJ_FASTCALL recff_bit64_tobit(jit_State *J, RecordFFData *rd) { CTState *cts = ctype_ctsG(J2G(J)); - TRef tr = crec_ct_tv(J, ctype_get(cts, CTID_INT64), 0, - J->base[0], &rd->argv[0]); + TRef tr = crec_bit64_arg(J, ctype_get(cts, CTID_INT64), + J->base[0], &rd->argv[0]); if (!tref_isinteger(tr)) tr = emitconv(tr, IRT_INT, tref_type(tr), 0); J->base[0] = tr; @@ -1822,7 +1833,7 @@ int LJ_FASTCALL recff_bit64_unary(jit_State *J, RecordFFData *rd) CTState *cts = ctype_ctsG(J2G(J)); CTypeID id = crec_bit64_type(cts, &rd->argv[0]); if (id) { - TRef tr = crec_ct_tv(J, ctype_get(cts, id), 0, J->base[0], &rd->argv[0]); + TRef tr = crec_bit64_arg(J, ctype_get(cts, id), J->base[0], &rd->argv[0]); tr = emitir(IRT(rd->data, id-CTID_INT64+IRT_I64), tr, 0); J->base[0] = emitir(IRTG(IR_CNEWI, IRT_CDATA), lj_ir_kint(J, id), tr); return 1; @@ -1842,9 +1853,9 @@ int LJ_FASTCALL recff_bit64_nary(jit_State *J, RecordFFData *rd) if (id) { CType *ct = ctype_get(cts, id); uint32_t ot = IRT(rd->data, id-CTID_INT64+IRT_I64); - TRef tr = crec_ct_tv(J, ct, 0, J->base[0], &rd->argv[0]); + TRef tr = crec_bit64_arg(J, ct, J->base[0], &rd->argv[0]); for (i = 1; J->base[i] != 0; i++) { - TRef tr2 = crec_ct_tv(J, ct, 0, J->base[i], &rd->argv[i]); + TRef tr2 = crec_bit64_arg(J, ct, J->base[i], &rd->argv[i]); tr = emitir(ot, tr, tr2); } J->base[0] = emitir(IRTG(IR_CNEWI, IRT_CDATA), lj_ir_kint(J, id), tr); @@ -1859,15 +1870,15 @@ int LJ_FASTCALL recff_bit64_shift(jit_State *J, RecordFFData *rd) CTypeID id; TRef tsh = 0; if (J->base[0] && tref_iscdata(J->base[1])) { - tsh = crec_ct_tv(J, ctype_get(cts, CTID_INT64), 0, - J->base[1], &rd->argv[1]); + tsh = crec_bit64_arg(J, ctype_get(cts, CTID_INT64), + J->base[1], &rd->argv[1]); if (!tref_isinteger(tsh)) tsh = emitconv(tsh, IRT_INT, tref_type(tsh), 0); J->base[1] = tsh; } id = crec_bit64_type(cts, &rd->argv[0]); if (id) { - TRef tr = crec_ct_tv(J, ctype_get(cts, id), 0, J->base[0], &rd->argv[0]); + TRef tr = crec_bit64_arg(J, ctype_get(cts, id), J->base[0], &rd->argv[0]); uint32_t op = rd->data; if (!tsh) tsh = lj_opt_narrow_tobit(J, J->base[1]); if (!(op < IR_BROL ? LJ_TARGET_MASKSHIFT : LJ_TARGET_MASKROT) && @@ -1897,7 +1908,7 @@ TRef recff_bit64_tohex(jit_State *J, RecordFFData *rd, TRef hdr) CTypeID id2 = 0; n = (int32_t)lj_carith_check64(J->L, 2, &id2); if (id2) - trsf = crec_ct_tv(J, ctype_get(cts, CTID_INT32), 0, trsf, &rd->argv[1]); + trsf = crec_bit64_arg(J, ctype_get(cts, CTID_INT32), trsf, &rd->argv[1]); else trsf = lj_opt_narrow_tobit(J, trsf); emitir(IRTGI(IR_EQ), trsf, lj_ir_kint(J, n)); /* Specialize to n. */ @@ -1908,7 +1919,7 @@ TRef recff_bit64_tohex(jit_State *J, RecordFFData *rd, TRef hdr) if ((uint32_t)n > 254) n = 254; sf |= ((SFormat)((n+1)&255) << STRFMT_SH_PREC); if (id) { - tr = crec_ct_tv(J, ctype_get(cts, id), 0, J->base[0], &rd->argv[0]); + tr = crec_bit64_arg(J, ctype_get(cts, id), J->base[0], &rd->argv[0]); if (n < 16) tr = emitir(IRT(IR_BAND, IRT_U64), tr, lj_ir_kint64(J, ((uint64_t)1 << 4*n)-1));