After more thought, I think that code is probably correct. Here's my take.
FT_Face is a pointer, and using 'face' is creating a new CDATA object (also a pointer) and copying the value of the pointer that is already a valid object (until the assignment finishes) and initialized with what FT_Open_Face set it to.
The catch is that a CDATA pointer does not need extra storage beyond itself. Since the new object is a CDATA pointer object, has a valid value, and is referenced, it won't vanish. If the container object used for calling FT_Open_Face vanishes, that won't have consequences because the value is already safe within the new CDATA object.
That's a different to what I was doing that caused a crash:
Code: Select all
ptr = ffi.new('double[?]', 10) -- This creates *both* a buffer and a CDATA pointer object.
-- The buffer is NOT contained in the CDATA object, but set up to be
-- freed on GC of the pointer object.
ptr = ptr - 1 -- This creates a new CDATA object: a pointer with the value of the previous one minus 1.
-- The original reference is lost, therefore the buffer will be GC'd at some point,
-- but the value of this pointer will be preserved, so it will point to invalid memory.
In the FT case, the buffer is allocated by the FT library, therefore not GC'd by FFI.
Edit: I've just seen your edit. Got the assertion error with LÖVE 0.10.2 and 0.9.1, but not with 11.2 or 0.9.2. Investigating.