diff options
-rw-r--r-- | doc/ext_ffi_api.html | 8 | ||||
-rw-r--r-- | src/lib_ffi.c | 26 | ||||
-rw-r--r-- | src/lj_crecord.c | 34 | ||||
-rw-r--r-- | src/lj_crecord.h | 4 | ||||
-rw-r--r-- | src/lj_ir.h | 4 |
5 files changed, 57 insertions, 19 deletions
diff --git a/doc/ext_ffi_api.html b/doc/ext_ffi_api.html index f0c4de90..7c2e53dd 100644 --- a/doc/ext_ffi_api.html +++ b/doc/ext_ffi_api.html | |||
@@ -312,13 +312,13 @@ is converted to a <tt>"const void *"</tt>. | |||
312 | </p> | 312 | </p> |
313 | <p> | 313 | <p> |
314 | In the first syntax, <tt>len</tt> gives the number of bytes to copy. | 314 | In the first syntax, <tt>len</tt> gives the number of bytes to copy. |
315 | In case <tt>src</tt> is a Lua string, the maximum copy length is the | 315 | Caveat: if <tt>src</tt> is a Lua string, then <tt>len</tt> must not |
316 | number of bytes of the string plus a zero-terminator. Caveat: the | 316 | exceed <tt>#src+1</tt>. |
317 | copied data may not be zero-terminated if <tt>len ≤ #src</tt>. | ||
318 | </p> | 317 | </p> |
319 | <p> | 318 | <p> |
320 | In the second syntax, the source of the copy must be a Lua string. All | 319 | In the second syntax, the source of the copy must be a Lua string. All |
321 | bytes of the string plus a zero-terminator are copied to <tt>dst</tt>. | 320 | bytes of the string <em>plus a zero-terminator</em> are copied to |
321 | <tt>dst</tt> (i.e. <tt>#src+1</tt> bytes). | ||
322 | </p> | 322 | </p> |
323 | <p> | 323 | <p> |
324 | Performance notice: <tt>ffi.copy()</tt> may be used as a faster | 324 | Performance notice: <tt>ffi.copy()</tt> may be used as a faster |
diff --git a/src/lib_ffi.c b/src/lib_ffi.c index 53dd50a9..45065c12 100644 --- a/src/lib_ffi.c +++ b/src/lib_ffi.c | |||
@@ -455,29 +455,27 @@ LJLIB_CF(ffi_string) LJLIB_REC(.) | |||
455 | return 1; | 455 | return 1; |
456 | } | 456 | } |
457 | 457 | ||
458 | LJLIB_CF(ffi_copy) | 458 | LJLIB_CF(ffi_copy) LJLIB_REC(.) |
459 | { | 459 | { |
460 | void *dp = ffi_checkptr(L, 1, CTID_P_VOID); | 460 | void *dp = ffi_checkptr(L, 1, CTID_P_VOID); |
461 | void *sp = ffi_checkptr(L, 2, CTID_P_CVOID); | 461 | void *sp = ffi_checkptr(L, 2, CTID_P_CVOID); |
462 | TValue *o = L->base+1; | 462 | TValue *o = L->base+1; |
463 | CTSize sz; | 463 | CTSize len; |
464 | if (tvisstr(o) && o+1 >= L->top) { | 464 | if (tvisstr(o) && o+1 >= L->top) |
465 | sz = strV(o)->len+1; /* Copy Lua string including trailing '\0'. */ | 465 | len = strV(o)->len+1; /* Copy Lua string including trailing '\0'. */ |
466 | } else { | 466 | else |
467 | sz = (CTSize)ffi_checkint(L, 3); | 467 | len = (CTSize)ffi_checkint(L, 3); |
468 | if (tvisstr(o) && sz > strV(o)->len+1) | 468 | memcpy(dp, sp, len); |
469 | sz = strV(o)->len+1; /* Max. copy length is string length. */ | ||
470 | } | ||
471 | memcpy(dp, sp, sz); | ||
472 | return 0; | 469 | return 0; |
473 | } | 470 | } |
474 | 471 | ||
475 | LJLIB_CF(ffi_fill) | 472 | LJLIB_CF(ffi_fill) LJLIB_REC(.) |
476 | { | 473 | { |
477 | void *dp = ffi_checkptr(L, 1, CTID_P_VOID); | 474 | void *dp = ffi_checkptr(L, 1, CTID_P_VOID); |
478 | CTSize sz = (CTSize)ffi_checkint(L, 2); | 475 | CTSize len = (CTSize)ffi_checkint(L, 2); |
479 | int32_t fill = lj_lib_optint(L, 3, 0); | 476 | int32_t fill = 0; |
480 | memset(dp, fill, sz); | 477 | if (L->base+2 < L->top && !tvisnil(L->base+2)) fill = ffi_checkint(L, 3); |
478 | memset(dp, fill, len); | ||
481 | return 0; | 479 | return 0; |
482 | } | 480 | } |
483 | 481 | ||
diff --git a/src/lj_crecord.c b/src/lj_crecord.c index ea18f75f..8e68a5d6 100644 --- a/src/lj_crecord.c +++ b/src/lj_crecord.c | |||
@@ -974,6 +974,40 @@ void LJ_FASTCALL recff_ffi_string(jit_State *J, RecordFFData *rd) | |||
974 | } /* else: interpreter will throw. */ | 974 | } /* else: interpreter will throw. */ |
975 | } | 975 | } |
976 | 976 | ||
977 | void LJ_FASTCALL recff_ffi_copy(jit_State *J, RecordFFData *rd) | ||
978 | { | ||
979 | CTState *cts = ctype_ctsG(J2G(J)); | ||
980 | TRef trdst = J->base[0], trsrc = J->base[1], trlen = J->base[2]; | ||
981 | if (trdst && trsrc && (trlen || tref_isstr(trsrc))) { | ||
982 | trdst = crec_ct_tv(J, ctype_get(cts, CTID_P_VOID), 0, trdst, &rd->argv[0]); | ||
983 | trsrc = crec_ct_tv(J, ctype_get(cts, CTID_P_CVOID), 0, trsrc, &rd->argv[1]); | ||
984 | if (trlen) { | ||
985 | trlen = crec_toint(J, cts, trlen, &rd->argv[2]); | ||
986 | } else { | ||
987 | trlen = emitir(IRTI(IR_FLOAD), trsrc, IRFL_STR_LEN); | ||
988 | trlen = emitir(IRTI(IR_ADD), trlen, lj_ir_kint(J, 1)); | ||
989 | } | ||
990 | lj_ir_call(J, IRCALL_memcpy, trdst, trsrc, trlen); | ||
991 | emitir(IRT(IR_XBAR, IRT_NIL), 0, 0); | ||
992 | } /* else: interpreter will throw. */ | ||
993 | } | ||
994 | |||
995 | void LJ_FASTCALL recff_ffi_fill(jit_State *J, RecordFFData *rd) | ||
996 | { | ||
997 | CTState *cts = ctype_ctsG(J2G(J)); | ||
998 | TRef tr = J->base[0], trlen = J->base[1], trfill = J->base[2]; | ||
999 | if (tr && trlen) { | ||
1000 | tr = crec_ct_tv(J, ctype_get(cts, CTID_P_VOID), 0, tr, &rd->argv[0]); | ||
1001 | trlen = crec_toint(J, cts, trlen, &rd->argv[1]); | ||
1002 | if (trfill) | ||
1003 | trfill = crec_toint(J, cts, trfill, &rd->argv[2]); | ||
1004 | else | ||
1005 | trfill = lj_ir_kint(J, 0); | ||
1006 | lj_ir_call(J, IRCALL_memset, tr, trfill, trlen); | ||
1007 | emitir(IRT(IR_XBAR, IRT_NIL), 0, 0); | ||
1008 | } /* else: interpreter will throw. */ | ||
1009 | } | ||
1010 | |||
977 | /* -- Miscellaneous library functions ------------------------------------- */ | 1011 | /* -- Miscellaneous library functions ------------------------------------- */ |
978 | 1012 | ||
979 | void LJ_FASTCALL lj_crecord_tonumber(jit_State *J, RecordFFData *rd) | 1013 | void LJ_FASTCALL lj_crecord_tonumber(jit_State *J, RecordFFData *rd) |
diff --git a/src/lj_crecord.h b/src/lj_crecord.h index 2b6c3ec6..1714f1c4 100644 --- a/src/lj_crecord.h +++ b/src/lj_crecord.h | |||
@@ -17,6 +17,8 @@ LJ_FUNC void LJ_FASTCALL recff_cdata_arith(jit_State *J, RecordFFData *rd); | |||
17 | LJ_FUNC void LJ_FASTCALL recff_clib_index(jit_State *J, RecordFFData *rd); | 17 | LJ_FUNC void LJ_FASTCALL recff_clib_index(jit_State *J, RecordFFData *rd); |
18 | LJ_FUNC void LJ_FASTCALL recff_ffi_new(jit_State *J, RecordFFData *rd); | 18 | LJ_FUNC void LJ_FASTCALL recff_ffi_new(jit_State *J, RecordFFData *rd); |
19 | LJ_FUNC void LJ_FASTCALL recff_ffi_string(jit_State *J, RecordFFData *rd); | 19 | LJ_FUNC void LJ_FASTCALL recff_ffi_string(jit_State *J, RecordFFData *rd); |
20 | LJ_FUNC void LJ_FASTCALL recff_ffi_copy(jit_State *J, RecordFFData *rd); | ||
21 | LJ_FUNC void LJ_FASTCALL recff_ffi_fill(jit_State *J, RecordFFData *rd); | ||
20 | LJ_FUNC void LJ_FASTCALL lj_crecord_tonumber(jit_State *J, RecordFFData *rd); | 22 | LJ_FUNC void LJ_FASTCALL lj_crecord_tonumber(jit_State *J, RecordFFData *rd); |
21 | #else | 23 | #else |
22 | #define recff_cdata_index recff_nyi | 24 | #define recff_cdata_index recff_nyi |
@@ -25,6 +27,8 @@ LJ_FUNC void LJ_FASTCALL lj_crecord_tonumber(jit_State *J, RecordFFData *rd); | |||
25 | #define recff_clib_index recff_nyi | 27 | #define recff_clib_index recff_nyi |
26 | #define recff_ffi_new recff_nyi | 28 | #define recff_ffi_new recff_nyi |
27 | #define recff_ffi_string recff_nyi | 29 | #define recff_ffi_string recff_nyi |
30 | #define recff_ffi_copy recff_nyi | ||
31 | #define recff_ffi_fill recff_nyi | ||
28 | #endif | 32 | #endif |
29 | 33 | ||
30 | #endif | 34 | #endif |
diff --git a/src/lj_ir.h b/src/lj_ir.h index a29fca6f..f9ca4627 100644 --- a/src/lj_ir.h +++ b/src/lj_ir.h | |||
@@ -276,7 +276,9 @@ typedef struct CCallInfo { | |||
276 | _(lj_carith_modu64, ARG2_64, N, U64, CCI_NOFPRCLOBBER) \ | 276 | _(lj_carith_modu64, ARG2_64, N, U64, CCI_NOFPRCLOBBER) \ |
277 | _(lj_carith_powi64, ARG2_64, N, I64, CCI_NOFPRCLOBBER) \ | 277 | _(lj_carith_powi64, ARG2_64, N, I64, CCI_NOFPRCLOBBER) \ |
278 | _(lj_carith_powu64, ARG2_64, N, U64, CCI_NOFPRCLOBBER) \ | 278 | _(lj_carith_powu64, ARG2_64, N, U64, CCI_NOFPRCLOBBER) \ |
279 | _(strlen, 1, N, INT, 0) | 279 | _(strlen, 1, N, INTP, 0) \ |
280 | _(memcpy, 3, S, PTR, 0) \ | ||
281 | _(memset, 3, S, PTR, 0) | ||
280 | #else | 282 | #else |
281 | #define IRCALLDEF_FFI(_) | 283 | #define IRCALLDEF_FFI(_) |
282 | #endif | 284 | #endif |