Skip to content

Commit

Permalink
FFI: Support FFI numbers in string.format() and buf:putf().
Browse files Browse the repository at this point in the history
  • Loading branch information
Mike Pall committed Jun 3, 2021
1 parent 6913808 commit 1b7171c
Show file tree
Hide file tree
Showing 4 changed files with 47 additions and 6 deletions.
9 changes: 9 additions & 0 deletions src/lj_crecord.c
Original file line number Diff line number Diff line change
Expand Up @@ -1913,6 +1913,15 @@ void LJ_FASTCALL lj_crecord_tonumber(jit_State *J, RecordFFData *rd)
}
}

TRef lj_crecord_loadiu64(jit_State *J, TRef tr, cTValue *o)
{
CTypeID id = argv2cdata(J, tr, o)->ctypeid;
if (!(id == CTID_INT64 || id == CTID_UINT64))
lj_trace_err(J, LJ_TRERR_BADTYPE);
return emitir(IRT(IR_FLOAD, id == CTID_INT64 ? IRT_I64 : IRT_U64), tr,
IRFL_CDATA_INT64);
}

#undef IR
#undef emitir
#undef emitconv
Expand Down
1 change: 1 addition & 0 deletions src/lj_crecord.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ 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);
LJ_FUNC TRef lj_crecord_loadiu64(jit_State *J, TRef tr, cTValue *o);
#endif

#endif
11 changes: 10 additions & 1 deletion src/lj_ffrecord.c
Original file line number Diff line number Diff line change
Expand Up @@ -961,8 +961,17 @@ static void LJ_FASTCALL recff_string_format(jit_State *J, RecordFFData *rd)
case STRFMT_INT:
id = IRCALL_lj_strfmt_putfnum_int;
handle_int:
if (!tref_isinteger(tra))
if (!tref_isinteger(tra)) {
#if LJ_HASFFI
if (tref_iscdata(tra)) {
tra = lj_crecord_loadiu64(J, tra, &rd->argv[arg-1]);
tr = lj_ir_call(J, IRCALL_lj_strfmt_putfxint, tr, trsf, tra);
lj_needsplit(J);
break;
}
#endif
goto handle_num;
}
if (sf == STRFMT_INT) { /* Shortcut for plain %d. */
tr = emitir(IRTG(IR_BUFPUT, IRT_PGC), tr,
emitir(IRT(IR_TOSTR, IRT_STR), tra, IRTOSTR_INT));
Expand Down
32 changes: 27 additions & 5 deletions src/lj_strfmt.c
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,9 @@
#include "lj_state.h"
#include "lj_char.h"
#include "lj_strfmt.h"
#if LJ_HASFFI
#include "lj_ctype.h"
#endif
#include "lj_lib.h"

/* -- Format parser ------------------------------------------------------- */
Expand Down Expand Up @@ -392,15 +395,34 @@ int lj_strfmt_putarg(lua_State *L, SBuf *sb, int arg, int retry)
lj_strfmt_putint(sb, k); /* Shortcut for plain %d. */
else
lj_strfmt_putfxint(sb, sf, k);
} else {
lj_strfmt_putfnum_int(sb, sf, lj_lib_checknum(L, arg));
break;
}
#if LJ_HASFFI
if (tviscdata(o)) {
GCcdata *cd = cdataV(o);
if (cd->ctypeid == CTID_INT64 || cd->ctypeid == CTID_UINT64) {
lj_strfmt_putfxint(sb, sf, *(uint64_t *)cdataptr(cd));
break;
}
}
#endif
lj_strfmt_putfnum_int(sb, sf, lj_lib_checknum(L, arg));
break;
case STRFMT_UINT:
if (tvisint(o))
if (tvisint(o)) {
lj_strfmt_putfxint(sb, sf, intV(o));
else
lj_strfmt_putfnum_uint(sb, sf, lj_lib_checknum(L, arg));
break;
}
#if LJ_HASFFI
if (tviscdata(o)) {
GCcdata *cd = cdataV(o);
if (cd->ctypeid == CTID_INT64 || cd->ctypeid == CTID_UINT64) {
lj_strfmt_putfxint(sb, sf, *(uint64_t *)cdataptr(cd));
break;
}
}
#endif
lj_strfmt_putfnum_uint(sb, sf, lj_lib_checknum(L, arg));
break;
case STRFMT_NUM:
lj_strfmt_putfnum(sb, sf, lj_lib_checknum(L, arg));
Expand Down

1 comment on commit 1b7171c

@koyudin
Copy link

@koyudin koyudin commented on 1b7171c Jun 3, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Many thanks for that improvement!

Please sign in to comment.