diff options
author | Mike Pall <mike> | 2011-02-07 17:13:14 +0100 |
---|---|---|
committer | Mike Pall <mike> | 2011-02-07 17:13:14 +0100 |
commit | 51e8fe9cf0738706dbcaae51774faffebfa389f0 (patch) | |
tree | e4add3595dc3fd09146a8aefeaac5d08bc384d8c /src | |
parent | 8da287cab809adbc29b8750345773f7f901a7a27 (diff) | |
download | luajit-51e8fe9cf0738706dbcaae51774faffebfa389f0.tar.gz luajit-51e8fe9cf0738706dbcaae51774faffebfa389f0.tar.bz2 luajit-51e8fe9cf0738706dbcaae51774faffebfa389f0.zip |
FFI: Allow cdata types for integer arguments of ffi.* functions.
Diffstat (limited to 'src')
-rw-r--r-- | src/lib_ffi.c | 22 | ||||
-rw-r--r-- | src/lj_crecord.c | 7 |
2 files changed, 23 insertions, 6 deletions
diff --git a/src/lib_ffi.c b/src/lib_ffi.c index 26e18183..53dd50a9 100644 --- a/src/lib_ffi.c +++ b/src/lib_ffi.c | |||
@@ -78,6 +78,18 @@ static void *ffi_checkptr(lua_State *L, int narg, CTypeID id) | |||
78 | return p; | 78 | return p; |
79 | } | 79 | } |
80 | 80 | ||
81 | /* Convert argument to int32_t. */ | ||
82 | static int32_t ffi_checkint(lua_State *L, int narg) | ||
83 | { | ||
84 | CTState *cts = ctype_cts(L); | ||
85 | TValue *o = L->base + narg-1; | ||
86 | int32_t i; | ||
87 | if (o >= L->top) | ||
88 | lj_err_arg(L, narg, LJ_ERR_NOVAL); | ||
89 | lj_cconv_ct_tv(cts, ctype_get(cts, CTID_INT32), (uint8_t *)&i, o, 0); | ||
90 | return i; | ||
91 | } | ||
92 | |||
81 | /* -- C type metamethods -------------------------------------------------- */ | 93 | /* -- C type metamethods -------------------------------------------------- */ |
82 | 94 | ||
83 | #define LJLIB_MODULE_ffi_meta | 95 | #define LJLIB_MODULE_ffi_meta |
@@ -324,7 +336,7 @@ LJLIB_CF(ffi_new) LJLIB_REC(.) | |||
324 | if ((info & CTF_VLA)) { | 336 | if ((info & CTF_VLA)) { |
325 | o++; | 337 | o++; |
326 | sz = lj_ctype_vlsize(cts, ctype_raw(cts, id), | 338 | sz = lj_ctype_vlsize(cts, ctype_raw(cts, id), |
327 | (CTSize)lj_lib_checkint(L, 2)); | 339 | (CTSize)ffi_checkint(L, 2)); |
328 | } | 340 | } |
329 | if (sz == CTSIZE_INVALID) | 341 | if (sz == CTSIZE_INVALID) |
330 | lj_err_arg(L, 1, LJ_ERR_FFI_INVSIZE); | 342 | lj_err_arg(L, 1, LJ_ERR_FFI_INVSIZE); |
@@ -361,7 +373,7 @@ LJLIB_CF(ffi_sizeof) | |||
361 | } else { | 373 | } else { |
362 | CType *ct = lj_ctype_rawref(cts, id); | 374 | CType *ct = lj_ctype_rawref(cts, id); |
363 | if (ctype_isvltype(ct->info)) | 375 | if (ctype_isvltype(ct->info)) |
364 | sz = lj_ctype_vlsize(cts, ct, (CTSize)lj_lib_checkint(L, 2)); | 376 | sz = lj_ctype_vlsize(cts, ct, (CTSize)ffi_checkint(L, 2)); |
365 | else | 377 | else |
366 | sz = ctype_hassize(ct->info) ? ct->size : CTSIZE_INVALID; | 378 | sz = ctype_hassize(ct->info) ? ct->size : CTSIZE_INVALID; |
367 | if (LJ_UNLIKELY(sz == CTSIZE_INVALID)) { | 379 | if (LJ_UNLIKELY(sz == CTSIZE_INVALID)) { |
@@ -431,7 +443,7 @@ LJLIB_CF(ffi_string) LJLIB_REC(.) | |||
431 | const char *p; | 443 | const char *p; |
432 | size_t len; | 444 | size_t len; |
433 | if (o+1 < L->top) { | 445 | if (o+1 < L->top) { |
434 | len = (size_t)lj_lib_checkint(L, 2); | 446 | len = (size_t)ffi_checkint(L, 2); |
435 | lj_cconv_ct_tv(cts, ctype_get(cts, CTID_P_CVOID), (uint8_t *)&p, o, 0); | 447 | lj_cconv_ct_tv(cts, ctype_get(cts, CTID_P_CVOID), (uint8_t *)&p, o, 0); |
436 | } else { | 448 | } else { |
437 | lj_cconv_ct_tv(cts, ctype_get(cts, CTID_P_CCHAR), (uint8_t *)&p, o, 0); | 449 | lj_cconv_ct_tv(cts, ctype_get(cts, CTID_P_CCHAR), (uint8_t *)&p, o, 0); |
@@ -452,7 +464,7 @@ LJLIB_CF(ffi_copy) | |||
452 | if (tvisstr(o) && o+1 >= L->top) { | 464 | if (tvisstr(o) && o+1 >= L->top) { |
453 | sz = strV(o)->len+1; /* Copy Lua string including trailing '\0'. */ | 465 | sz = strV(o)->len+1; /* Copy Lua string including trailing '\0'. */ |
454 | } else { | 466 | } else { |
455 | sz = (CTSize)lj_lib_checkint(L, 3); | 467 | sz = (CTSize)ffi_checkint(L, 3); |
456 | if (tvisstr(o) && sz > strV(o)->len+1) | 468 | if (tvisstr(o) && sz > strV(o)->len+1) |
457 | sz = strV(o)->len+1; /* Max. copy length is string length. */ | 469 | sz = strV(o)->len+1; /* Max. copy length is string length. */ |
458 | } | 470 | } |
@@ -463,7 +475,7 @@ LJLIB_CF(ffi_copy) | |||
463 | LJLIB_CF(ffi_fill) | 475 | LJLIB_CF(ffi_fill) |
464 | { | 476 | { |
465 | void *dp = ffi_checkptr(L, 1, CTID_P_VOID); | 477 | void *dp = ffi_checkptr(L, 1, CTID_P_VOID); |
466 | CTSize sz = (CTSize)lj_lib_checkint(L, 2); | 478 | CTSize sz = (CTSize)ffi_checkint(L, 2); |
467 | int32_t fill = lj_lib_optint(L, 3, 0); | 479 | int32_t fill = lj_lib_optint(L, 3, 0); |
468 | memset(dp, fill, sz); | 480 | memset(dp, fill, sz); |
469 | return 0; | 481 | return 0; |
diff --git a/src/lj_crecord.c b/src/lj_crecord.c index 8473ee45..44c5844a 100644 --- a/src/lj_crecord.c +++ b/src/lj_crecord.c | |||
@@ -947,6 +947,11 @@ void LJ_FASTCALL recff_clib_index(jit_State *J, RecordFFData *rd) | |||
947 | 947 | ||
948 | /* -- FFI library functions ----------------------------------------------- */ | 948 | /* -- FFI library functions ----------------------------------------------- */ |
949 | 949 | ||
950 | static TRef crec_toint(jit_State *J, CTState *cts, TRef sp, TValue *sval) | ||
951 | { | ||
952 | return crec_ct_tv(J, ctype_get(cts, CTID_INT32), 0, sp, sval); | ||
953 | } | ||
954 | |||
950 | void LJ_FASTCALL recff_ffi_new(jit_State *J, RecordFFData *rd) | 955 | void LJ_FASTCALL recff_ffi_new(jit_State *J, RecordFFData *rd) |
951 | { | 956 | { |
952 | crec_alloc(J, rd, argv2ctype(J, J->base[0], &rd->argv[0])); | 957 | crec_alloc(J, rd, argv2ctype(J, J->base[0], &rd->argv[0])); |
@@ -959,7 +964,7 @@ void LJ_FASTCALL recff_ffi_string(jit_State *J, RecordFFData *rd) | |||
959 | if (tr) { | 964 | if (tr) { |
960 | TRef trlen = J->base[1]; | 965 | TRef trlen = J->base[1]; |
961 | if (trlen) { | 966 | if (trlen) { |
962 | trlen = lj_ir_toint(J, trlen); | 967 | trlen = crec_toint(J, cts, trlen, &rd->argv[1]); |
963 | tr = crec_ct_tv(J, ctype_get(cts, CTID_P_CVOID), 0, tr, &rd->argv[0]); | 968 | tr = crec_ct_tv(J, ctype_get(cts, CTID_P_CVOID), 0, tr, &rd->argv[0]); |
964 | } else { | 969 | } else { |
965 | tr = crec_ct_tv(J, ctype_get(cts, CTID_P_CCHAR), 0, tr, &rd->argv[0]); | 970 | tr = crec_ct_tv(J, ctype_get(cts, CTID_P_CCHAR), 0, tr, &rd->argv[0]); |