diff options
| author | Mike Pall <mike> | 2021-06-03 03:22:58 +0200 |
|---|---|---|
| committer | Mike Pall <mike> | 2021-06-03 03:22:58 +0200 |
| commit | 1b7171c339a8d33cb1fd332e31787ebc23266f10 (patch) | |
| tree | e58ba6c2ac54dec8f6574b3c574aa1b99360719a /src | |
| parent | 69138082a3166105faa8cbb25fadb1e4298686c0 (diff) | |
| download | luajit-1b7171c339a8d33cb1fd332e31787ebc23266f10.tar.gz luajit-1b7171c339a8d33cb1fd332e31787ebc23266f10.tar.bz2 luajit-1b7171c339a8d33cb1fd332e31787ebc23266f10.zip | |
FFI: Support FFI numbers in string.format() and buf:putf().
Diffstat (limited to 'src')
| -rw-r--r-- | src/lj_crecord.c | 9 | ||||
| -rw-r--r-- | src/lj_crecord.h | 1 | ||||
| -rw-r--r-- | src/lj_ffrecord.c | 11 | ||||
| -rw-r--r-- | src/lj_strfmt.c | 32 |
4 files changed, 47 insertions, 6 deletions
diff --git a/src/lj_crecord.c b/src/lj_crecord.c index b0de5423..aa4c5842 100644 --- a/src/lj_crecord.c +++ b/src/lj_crecord.c | |||
| @@ -1913,6 +1913,15 @@ void LJ_FASTCALL lj_crecord_tonumber(jit_State *J, RecordFFData *rd) | |||
| 1913 | } | 1913 | } |
| 1914 | } | 1914 | } |
| 1915 | 1915 | ||
| 1916 | TRef lj_crecord_loadiu64(jit_State *J, TRef tr, cTValue *o) | ||
| 1917 | { | ||
| 1918 | CTypeID id = argv2cdata(J, tr, o)->ctypeid; | ||
| 1919 | if (!(id == CTID_INT64 || id == CTID_UINT64)) | ||
| 1920 | lj_trace_err(J, LJ_TRERR_BADTYPE); | ||
| 1921 | return emitir(IRT(IR_FLOAD, id == CTID_INT64 ? IRT_I64 : IRT_U64), tr, | ||
| 1922 | IRFL_CDATA_INT64); | ||
| 1923 | } | ||
| 1924 | |||
| 1916 | #undef IR | 1925 | #undef IR |
| 1917 | #undef emitir | 1926 | #undef emitir |
| 1918 | #undef emitconv | 1927 | #undef emitconv |
diff --git a/src/lj_crecord.h b/src/lj_crecord.h index c6f39a67..1a3427bd 100644 --- a/src/lj_crecord.h +++ b/src/lj_crecord.h | |||
| @@ -33,6 +33,7 @@ LJ_FUNC int LJ_FASTCALL recff_bit64_shift(jit_State *J, RecordFFData *rd); | |||
| 33 | LJ_FUNC TRef recff_bit64_tohex(jit_State *J, RecordFFData *rd, TRef hdr); | 33 | LJ_FUNC TRef recff_bit64_tohex(jit_State *J, RecordFFData *rd, TRef hdr); |
| 34 | 34 | ||
| 35 | LJ_FUNC void LJ_FASTCALL lj_crecord_tonumber(jit_State *J, RecordFFData *rd); | 35 | LJ_FUNC void LJ_FASTCALL lj_crecord_tonumber(jit_State *J, RecordFFData *rd); |
| 36 | LJ_FUNC TRef lj_crecord_loadiu64(jit_State *J, TRef tr, cTValue *o); | ||
| 36 | #endif | 37 | #endif |
| 37 | 38 | ||
| 38 | #endif | 39 | #endif |
diff --git a/src/lj_ffrecord.c b/src/lj_ffrecord.c index 844fc497..d050d12d 100644 --- a/src/lj_ffrecord.c +++ b/src/lj_ffrecord.c | |||
| @@ -961,8 +961,17 @@ static void LJ_FASTCALL recff_string_format(jit_State *J, RecordFFData *rd) | |||
| 961 | case STRFMT_INT: | 961 | case STRFMT_INT: |
| 962 | id = IRCALL_lj_strfmt_putfnum_int; | 962 | id = IRCALL_lj_strfmt_putfnum_int; |
| 963 | handle_int: | 963 | handle_int: |
| 964 | if (!tref_isinteger(tra)) | 964 | if (!tref_isinteger(tra)) { |
| 965 | #if LJ_HASFFI | ||
| 966 | if (tref_iscdata(tra)) { | ||
| 967 | tra = lj_crecord_loadiu64(J, tra, &rd->argv[arg-1]); | ||
| 968 | tr = lj_ir_call(J, IRCALL_lj_strfmt_putfxint, tr, trsf, tra); | ||
| 969 | lj_needsplit(J); | ||
| 970 | break; | ||
| 971 | } | ||
| 972 | #endif | ||
| 965 | goto handle_num; | 973 | goto handle_num; |
| 974 | } | ||
| 966 | if (sf == STRFMT_INT) { /* Shortcut for plain %d. */ | 975 | if (sf == STRFMT_INT) { /* Shortcut for plain %d. */ |
| 967 | tr = emitir(IRTG(IR_BUFPUT, IRT_PGC), tr, | 976 | tr = emitir(IRTG(IR_BUFPUT, IRT_PGC), tr, |
| 968 | emitir(IRT(IR_TOSTR, IRT_STR), tra, IRTOSTR_INT)); | 977 | emitir(IRT(IR_TOSTR, IRT_STR), tra, IRTOSTR_INT)); |
diff --git a/src/lj_strfmt.c b/src/lj_strfmt.c index 5826b539..7b073470 100644 --- a/src/lj_strfmt.c +++ b/src/lj_strfmt.c | |||
| @@ -16,6 +16,9 @@ | |||
| 16 | #include "lj_state.h" | 16 | #include "lj_state.h" |
| 17 | #include "lj_char.h" | 17 | #include "lj_char.h" |
| 18 | #include "lj_strfmt.h" | 18 | #include "lj_strfmt.h" |
| 19 | #if LJ_HASFFI | ||
| 20 | #include "lj_ctype.h" | ||
| 21 | #endif | ||
| 19 | #include "lj_lib.h" | 22 | #include "lj_lib.h" |
| 20 | 23 | ||
| 21 | /* -- Format parser ------------------------------------------------------- */ | 24 | /* -- Format parser ------------------------------------------------------- */ |
| @@ -392,15 +395,34 @@ int lj_strfmt_putarg(lua_State *L, SBuf *sb, int arg, int retry) | |||
| 392 | lj_strfmt_putint(sb, k); /* Shortcut for plain %d. */ | 395 | lj_strfmt_putint(sb, k); /* Shortcut for plain %d. */ |
| 393 | else | 396 | else |
| 394 | lj_strfmt_putfxint(sb, sf, k); | 397 | lj_strfmt_putfxint(sb, sf, k); |
| 395 | } else { | 398 | break; |
| 396 | lj_strfmt_putfnum_int(sb, sf, lj_lib_checknum(L, arg)); | 399 | } |
| 400 | #if LJ_HASFFI | ||
| 401 | if (tviscdata(o)) { | ||
| 402 | GCcdata *cd = cdataV(o); | ||
| 403 | if (cd->ctypeid == CTID_INT64 || cd->ctypeid == CTID_UINT64) { | ||
| 404 | lj_strfmt_putfxint(sb, sf, *(uint64_t *)cdataptr(cd)); | ||
| 405 | break; | ||
| 406 | } | ||
| 397 | } | 407 | } |
| 408 | #endif | ||
| 409 | lj_strfmt_putfnum_int(sb, sf, lj_lib_checknum(L, arg)); | ||
| 398 | break; | 410 | break; |
| 399 | case STRFMT_UINT: | 411 | case STRFMT_UINT: |
| 400 | if (tvisint(o)) | 412 | if (tvisint(o)) { |
| 401 | lj_strfmt_putfxint(sb, sf, intV(o)); | 413 | lj_strfmt_putfxint(sb, sf, intV(o)); |
| 402 | else | 414 | break; |
| 403 | lj_strfmt_putfnum_uint(sb, sf, lj_lib_checknum(L, arg)); | 415 | } |
| 416 | #if LJ_HASFFI | ||
| 417 | if (tviscdata(o)) { | ||
| 418 | GCcdata *cd = cdataV(o); | ||
| 419 | if (cd->ctypeid == CTID_INT64 || cd->ctypeid == CTID_UINT64) { | ||
| 420 | lj_strfmt_putfxint(sb, sf, *(uint64_t *)cdataptr(cd)); | ||
| 421 | break; | ||
| 422 | } | ||
| 423 | } | ||
| 424 | #endif | ||
| 425 | lj_strfmt_putfnum_uint(sb, sf, lj_lib_checknum(L, arg)); | ||
| 404 | break; | 426 | break; |
| 405 | case STRFMT_NUM: | 427 | case STRFMT_NUM: |
| 406 | lj_strfmt_putfnum(sb, sf, lj_lib_checknum(L, arg)); | 428 | lj_strfmt_putfnum(sb, sf, lj_lib_checknum(L, arg)); |
