You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
The following example exhausted the FFI ctypes table:
local ffi =require("ffi")
ffi.cdef ([[typedef void (cb)();]])
for i=1,40000dolocal pok, pp =pcall(ffi.cast, "cb*", function() end)
ifnot pok thenprint(pp, " at ", i)
breakend
pp:free()
end
ouputs table overflow at 32539
Although there're tons of solutions including using ffi.typeof("cb*") to reuse the type,
define it with typedef void (*cb)(); and then use as ffi.cast("cb", function() end).
It may still be a surprise to users as ffi.cast("cb*", function() end) implictly creates
one CT_PTR type and one CT_FUNC type each time it's called.
Consider the case for example a struct, there's no issue with the following code:
local ffi =require("ffi")
ffi.cdef ([[typedef struct P {} P;]])
for i=1,40000do-- parses as a PTR and no new ctypes createdlocal pok =pcall(ffi.new, "P*")
ifnot pok thenprint(pp, " at ", i)
breakendend
From the code https://github.com/LuaJIT/LuaJIT/blob/v2.1/src/lj_cparse.c#L886 I can see when parser parses a
function, it will always create a new ctype, no matter the context is ffi.cdef or ffi.new/cast. My question
is that is this by-purpose or is a bug?
The text was updated successfully, but these errors were encountered:
fffonion
changed the title
Duplicate ctype created with pointer callback cdef
Duplicate ctype created with pointer callback in FFI
Mar 25, 2021
MikePall
changed the title
Duplicate ctype created with pointer callback in FFI
FFI typedefs of functions (not function pointers)
Mar 25, 2021
One should always use C function pointers for the callback cast.
A typedef for a function (and not a function pointer) is an awkward corner of the C spec. IMHO there's no good reason to use them anywhere. Functions are not considered values in C, only pointers to functions are.
Following the C spec, every use of such a typedef creates a new function (and C compilers agree):
typedefint (func_t)(int);
func_tf1;
func_tf2;
is equivalent to
int f1(int);
int f2(int);
It's just that you can't dynamically create functions in C, which makes this less apparent.
So, yes, your FFI cast creates a new (anonymous) C function on every invocation. Also, the code in cp_decl_intern technically couldn't intern the function, because the ->next field is already used by the by-name-lookup hash table.
The following example exhausted the FFI ctypes table:
ouputs
table overflow at 32539
Although there're tons of solutions including using
ffi.typeof("cb*")
to reuse the type,define it with
typedef void (*cb)();
and then use asffi.cast("cb", function() end)
.It may still be a surprise to users as
ffi.cast("cb*", function() end)
implictly createsone CT_PTR type and one CT_FUNC type each time it's called.
Consider the case for example a struct, there's no issue with the following code:
From the code https://github.com/LuaJIT/LuaJIT/blob/v2.1/src/lj_cparse.c#L886 I can see when parser parses a
function, it will always create a new ctype, no matter the context is
ffi.cdef
orffi.new/cast
. My questionis that is this by-purpose or is a bug?
The text was updated successfully, but these errors were encountered: