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 | |
| 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.
| -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]); |
