aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMike Pall <mike>2021-06-03 03:22:58 +0200
committerMike Pall <mike>2021-06-03 03:22:58 +0200
commit1b7171c339a8d33cb1fd332e31787ebc23266f10 (patch)
treee58ba6c2ac54dec8f6574b3c574aa1b99360719a /src
parent69138082a3166105faa8cbb25fadb1e4298686c0 (diff)
downloadluajit-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.c9
-rw-r--r--src/lj_crecord.h1
-rw-r--r--src/lj_ffrecord.c11
-rw-r--r--src/lj_strfmt.c32
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
1916TRef 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);
33LJ_FUNC TRef recff_bit64_tohex(jit_State *J, RecordFFData *rd, TRef hdr); 33LJ_FUNC TRef recff_bit64_tohex(jit_State *J, RecordFFData *rd, TRef hdr);
34 34
35LJ_FUNC void LJ_FASTCALL lj_crecord_tonumber(jit_State *J, RecordFFData *rd); 35LJ_FUNC void LJ_FASTCALL lj_crecord_tonumber(jit_State *J, RecordFFData *rd);
36LJ_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));