aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMike Pall <mike>2011-02-07 23:49:27 +0100
committerMike Pall <mike>2011-02-07 23:49:27 +0100
commit7a37b93f1b40ba83cc68965b1c80c35363c1493d (patch)
treed60ad18e47839b3998e1191672249735c46a99cc
parentfb53d4aeb7590e0e8437b03589ef68adf4611570 (diff)
downloadluajit-7a37b93f1b40ba83cc68965b1c80c35363c1493d.tar.gz
luajit-7a37b93f1b40ba83cc68965b1c80c35363c1493d.tar.bz2
luajit-7a37b93f1b40ba83cc68965b1c80c35363c1493d.zip
FFI: Record ffi.copy() and ffi.fill().
-rw-r--r--doc/ext_ffi_api.html8
-rw-r--r--src/lib_ffi.c26
-rw-r--r--src/lj_crecord.c34
-rw-r--r--src/lj_crecord.h4
-rw-r--r--src/lj_ir.h4
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&nbsp;*"</tt>.
312</p> 312</p>
313<p> 313<p>
314In the first syntax, <tt>len</tt> gives the number of bytes to copy. 314In the first syntax, <tt>len</tt> gives the number of bytes to copy.
315In case <tt>src</tt> is a Lua string, the maximum copy length is the 315Caveat: if <tt>src</tt> is a Lua string, then <tt>len</tt> must not
316number of bytes of the string plus a zero-terminator. Caveat: the 316exceed <tt>#src+1</tt>.
317copied data may not be zero-terminated if <tt>len&nbsp;&le;&nbsp;#src</tt>.
318</p> 317</p>
319<p> 318<p>
320In the second syntax, the source of the copy must be a Lua string. All 319In the second syntax, the source of the copy must be a Lua string. All
321bytes of the string plus a zero-terminator are copied to <tt>dst</tt>. 320bytes 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>
324Performance notice: <tt>ffi.copy()</tt> may be used as a faster 324Performance 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
458LJLIB_CF(ffi_copy) 458LJLIB_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
475LJLIB_CF(ffi_fill) 472LJLIB_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
977void 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
995void 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
979void LJ_FASTCALL lj_crecord_tonumber(jit_State *J, RecordFFData *rd) 1013void 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);
17LJ_FUNC void LJ_FASTCALL recff_clib_index(jit_State *J, RecordFFData *rd); 17LJ_FUNC void LJ_FASTCALL recff_clib_index(jit_State *J, RecordFFData *rd);
18LJ_FUNC void LJ_FASTCALL recff_ffi_new(jit_State *J, RecordFFData *rd); 18LJ_FUNC void LJ_FASTCALL recff_ffi_new(jit_State *J, RecordFFData *rd);
19LJ_FUNC void LJ_FASTCALL recff_ffi_string(jit_State *J, RecordFFData *rd); 19LJ_FUNC void LJ_FASTCALL recff_ffi_string(jit_State *J, RecordFFData *rd);
20LJ_FUNC void LJ_FASTCALL recff_ffi_copy(jit_State *J, RecordFFData *rd);
21LJ_FUNC void LJ_FASTCALL recff_ffi_fill(jit_State *J, RecordFFData *rd);
20LJ_FUNC void LJ_FASTCALL lj_crecord_tonumber(jit_State *J, RecordFFData *rd); 22LJ_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