diff --git a/src/Makefile.dep b/src/Makefile.dep index 376e2d2f..0ea0d98e 100644 --- a/src/Makefile.dep +++ b/src/Makefile.dep @@ -88,10 +88,10 @@ lj_cparse.o: lj_cparse.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \ lj_frame.h lj_bc.h lj_vm.h lj_char.h lj_strscan.h lj_strfmt.h lj_crecord.o: lj_crecord.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \ lj_err.h lj_errmsg.h lj_tab.h lj_frame.h lj_bc.h lj_ctype.h lj_gc.h \ - lj_cdata.h lj_cparse.h lj_cconv.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_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_crecord.h lj_strfmt.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 diff --git a/src/lib_bit.c b/src/lib_bit.c index a258484d..a3f7c1ac 100644 --- a/src/lib_bit.c +++ b/src/lib_bit.c @@ -142,7 +142,7 @@ LJLIB_ASM_(bit_bxor) LJLIB_REC(bit_nary IR_BXOR) /* ------------------------------------------------------------------------ */ -LJLIB_CF(bit_tohex) +LJLIB_CF(bit_tohex) LJLIB_REC(.) { #if LJ_HASFFI CTypeID id = 0, id2 = 0; diff --git a/src/lj_crecord.c b/src/lj_crecord.c index 398ca2a7..b98bdbc6 100644 --- a/src/lj_crecord.c +++ b/src/lj_crecord.c @@ -17,6 +17,7 @@ #include "lj_cdata.h" #include "lj_cparse.h" #include "lj_cconv.h" +#include "lj_carith.h" #include "lj_clib.h" #include "lj_ccall.h" #include "lj_ff.h" @@ -30,6 +31,7 @@ #include "lj_snap.h" #include "lj_crecord.h" #include "lj_dispatch.h" +#include "lj_strfmt.h" /* Some local macros to save typing. Undef'd at the end. */ #define IR(ref) (&J->cur.ir[(ref)]) @@ -1720,6 +1722,41 @@ int LJ_FASTCALL recff_bit64_shift(jit_State *J, RecordFFData *rd) return 0; } +TRef recff_bit64_tohex(jit_State *J, RecordFFData *rd, TRef hdr) +{ + CTState *cts = ctype_ctsG(J2G(J)); + CTypeID id = crec_bit64_type(cts, &rd->argv[0]); + TRef tr, trsf = J->base[1]; + SFormat sf = (STRFMT_UINT|STRFMT_T_HEX); + int32_t n; + if (trsf) { + 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]); + else + trsf = lj_opt_narrow_tobit(J, trsf); + emitir(IRTGI(IR_EQ), trsf, lj_ir_kint(J, n)); /* Specialize to n. */ + } else { + n = id ? 16 : 8; + } + if (n < 0) { n = -n; sf |= STRFMT_F_UPPER; } + 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]); + if (n < 16) + tr = emitir(IRT(IR_BAND, IRT_U64), tr, + lj_ir_kint64(J, ((uint64_t)1 << 4*n)-1)); + } else { + tr = lj_opt_narrow_tobit(J, J->base[0]); + if (n < 8) + tr = emitir(IRTI(IR_BAND), tr, lj_ir_kint(J, (int32_t)((1u << 4*n)-1))); + tr = emitconv(tr, IRT_U64, IRT_INT, 0); /* No sign-extension. */ + lj_needsplit(J); + } + return lj_ir_call(J, IRCALL_lj_strfmt_putfxint, hdr, lj_ir_kint(J, sf), tr); +} + /* -- Miscellaneous library functions ------------------------------------- */ void LJ_FASTCALL lj_crecord_tonumber(jit_State *J, RecordFFData *rd) diff --git a/src/lj_crecord.h b/src/lj_crecord.h index 92d777b8..47c0a69d 100644 --- a/src/lj_crecord.h +++ b/src/lj_crecord.h @@ -30,6 +30,7 @@ LJ_FUNC void LJ_FASTCALL recff_bit64_tobit(jit_State *J, RecordFFData *rd); LJ_FUNC int LJ_FASTCALL recff_bit64_unary(jit_State *J, RecordFFData *rd); LJ_FUNC int LJ_FASTCALL recff_bit64_nary(jit_State *J, RecordFFData *rd); LJ_FUNC int LJ_FASTCALL recff_bit64_shift(jit_State *J, RecordFFData *rd); +LJ_FUNC TRef recff_bit64_tohex(jit_State *J, RecordFFData *rd, TRef hdr); LJ_FUNC void LJ_FASTCALL lj_crecord_tonumber(jit_State *J, RecordFFData *rd); #endif diff --git a/src/lj_ffrecord.c b/src/lj_ffrecord.c index 31f9b390..fcc46319 100644 --- a/src/lj_ffrecord.c +++ b/src/lj_ffrecord.c @@ -119,6 +119,13 @@ static void LJ_FASTCALL recff_c(jit_State *J, RecordFFData *rd) UNUSED(rd); } +/* Emit BUFHDR for the global temporary buffer. */ +static TRef recff_bufhdr(jit_State *J) +{ + return emitir(IRT(IR_BUFHDR, IRT_P32), + lj_ir_kptr(J, &J2G(J)->tmpbuf), IRBUFHDR_RESET); +} + /* -- Base library fast functions ----------------------------------------- */ static void LJ_FASTCALL recff_assert(jit_State *J, RecordFFData *rd) @@ -645,15 +652,19 @@ static void LJ_FASTCALL recff_bit_shift(jit_State *J, RecordFFData *rd) } } -/* -- String library fast functions --------------------------------------- */ - -/* Emit BUFHDR for the global temporary buffer. */ -static TRef recff_bufhdr(jit_State *J) +static void LJ_FASTCALL recff_bit_tohex(jit_State *J, RecordFFData *rd) { - return emitir(IRT(IR_BUFHDR, IRT_P32), - lj_ir_kptr(J, &J2G(J)->tmpbuf), IRBUFHDR_RESET); +#if LJ_HASFFI + TRef hdr = recff_bufhdr(J); + TRef tr = recff_bit64_tohex(J, rd, hdr); + J->base[0] = emitir(IRT(IR_BUFSTR, IRT_STR), tr, hdr); +#else + recff_nyiu(J); /* Don't bother working around this NYI. */ +#endif } +/* -- String library fast functions --------------------------------------- */ + /* Specialize to relative starting position for string. */ static TRef recff_string_start(jit_State *J, GCstr *s, int32_t *st, TRef tr, TRef trlen, TRef tr0)