From 51e8fe9cf0738706dbcaae51774faffebfa389f0 Mon Sep 17 00:00:00 2001 From: Mike Pall Date: Mon, 7 Feb 2011 17:13:14 +0100 Subject: [PATCH] FFI: Allow cdata types for integer arguments of ffi.* functions. --- src/lib_ffi.c | 22 +++++++++++++++++----- 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) return p; } +/* Convert argument to int32_t. */ +static int32_t ffi_checkint(lua_State *L, int narg) +{ + CTState *cts = ctype_cts(L); + TValue *o = L->base + narg-1; + int32_t i; + if (o >= L->top) + lj_err_arg(L, narg, LJ_ERR_NOVAL); + lj_cconv_ct_tv(cts, ctype_get(cts, CTID_INT32), (uint8_t *)&i, o, 0); + return i; +} + /* -- C type metamethods -------------------------------------------------- */ #define LJLIB_MODULE_ffi_meta @@ -324,7 +336,7 @@ LJLIB_CF(ffi_new) LJLIB_REC(.) if ((info & CTF_VLA)) { o++; sz = lj_ctype_vlsize(cts, ctype_raw(cts, id), - (CTSize)lj_lib_checkint(L, 2)); + (CTSize)ffi_checkint(L, 2)); } if (sz == CTSIZE_INVALID) lj_err_arg(L, 1, LJ_ERR_FFI_INVSIZE); @@ -361,7 +373,7 @@ LJLIB_CF(ffi_sizeof) } else { CType *ct = lj_ctype_rawref(cts, id); if (ctype_isvltype(ct->info)) - sz = lj_ctype_vlsize(cts, ct, (CTSize)lj_lib_checkint(L, 2)); + sz = lj_ctype_vlsize(cts, ct, (CTSize)ffi_checkint(L, 2)); else sz = ctype_hassize(ct->info) ? ct->size : CTSIZE_INVALID; if (LJ_UNLIKELY(sz == CTSIZE_INVALID)) { @@ -431,7 +443,7 @@ LJLIB_CF(ffi_string) LJLIB_REC(.) const char *p; size_t len; if (o+1 < L->top) { - len = (size_t)lj_lib_checkint(L, 2); + len = (size_t)ffi_checkint(L, 2); lj_cconv_ct_tv(cts, ctype_get(cts, CTID_P_CVOID), (uint8_t *)&p, o, 0); } else { lj_cconv_ct_tv(cts, ctype_get(cts, CTID_P_CCHAR), (uint8_t *)&p, o, 0); @@ -452,7 +464,7 @@ LJLIB_CF(ffi_copy) if (tvisstr(o) && o+1 >= L->top) { sz = strV(o)->len+1; /* Copy Lua string including trailing '\0'. */ } else { - sz = (CTSize)lj_lib_checkint(L, 3); + sz = (CTSize)ffi_checkint(L, 3); if (tvisstr(o) && sz > strV(o)->len+1) sz = strV(o)->len+1; /* Max. copy length is string length. */ } @@ -463,7 +475,7 @@ LJLIB_CF(ffi_copy) LJLIB_CF(ffi_fill) { void *dp = ffi_checkptr(L, 1, CTID_P_VOID); - CTSize sz = (CTSize)lj_lib_checkint(L, 2); + CTSize sz = (CTSize)ffi_checkint(L, 2); int32_t fill = lj_lib_optint(L, 3, 0); memset(dp, fill, sz); 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) /* -- FFI library functions ----------------------------------------------- */ +static TRef crec_toint(jit_State *J, CTState *cts, TRef sp, TValue *sval) +{ + return crec_ct_tv(J, ctype_get(cts, CTID_INT32), 0, sp, sval); +} + void LJ_FASTCALL recff_ffi_new(jit_State *J, RecordFFData *rd) { 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) if (tr) { TRef trlen = J->base[1]; if (trlen) { - trlen = lj_ir_toint(J, trlen); + trlen = crec_toint(J, cts, trlen, &rd->argv[1]); tr = crec_ct_tv(J, ctype_get(cts, CTID_P_CVOID), 0, tr, &rd->argv[0]); } else { tr = crec_ct_tv(J, ctype_get(cts, CTID_P_CCHAR), 0, tr, &rd->argv[0]);