cluaffiluajit

Is userdata in LuaJIT ffi garbage collected when it is returned from a C function by value?


I'm trying to figure out LuaJIT garbage collection when its FFI is involved. Let's say I have a function that returns a struct by value.

typedef struct MyTestData {
    int id;
    // ... other fields that may need finalizing/freeing
} MyTestData;

MyTestData createTestData(int id);
void deleteTestData(MyTestData data); // finalizes/frees the data in MyTestData fields

// and then I use the same in ffi.cdef and
local lib = ffi.load(LIBRARY_PATH)

My questions are:

  1. When I create a Lua variable by calling local v = lib.createTestData(25) and then v gets garbage collected (for example, going out of score with no other references), does it free the memory allocated for it even though createTestData returned the struct value, not a pointer to it?
  2. If I need additional cleanup of resources MyTestData may hold, and I create it like this: local v = ffi.gc(lib.createTestData(25), lib.deleteTestData), does it also automatically free the memory used by v when it goes out of scope after calling deleteTestData?

I'm asking this because the LuaJIT FFI docs and examples usually deal with pointers, mallocs and frees, whereas in my case what I have are values.


Solution

  • A parameter that does not fit into register (longer than 16 bytes for x64) is pre-allocated by caller and passed by pointer. That is, struct foo bar(...); is almost the same as struct foo* bar(struct foo*, ...);

    Or, from ffi's POV, local foo = bar(...) is equivalent to local foo = ffi.new(...); bar(foo, ...). So no extra precautions needed.