lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]

Hello List,

I was looking at liolib.c to see how userdata is used in real life, and
observed this:
lioblib exposes a userdata to lua that holds a FILE*. To do so it actually
creates a userdata that points to a pointer, this pointer being the FILE*.
This is necessary because the FILE structure whose FILE* we have is obtained
through an external allocation scheme with fopen(), therefore lua cannot
simply create a userdata containing a FILE structure (it is not exposed
anyway), then ask some C call to fill it accordingly. Thus, upon garbage
collection of the userdata, the __gc metamethod is called to close the file
(which actually does fclose(FILE*) thus freeing the structure), then the
memory block is garbage collected.

I was wondering if it could not be possible in this particular case, to
remove the need for this lonely intermediate pointer ?
This could be done through a return value of the metamethod, that, if
non-nil/false, tells the gc if actual collection of its memory area is
To enable this, one would only have to be able to tell lua, when creating a
userdata, if this memory block is needed, or if it can use the provided
pointer as is.

For example, liolib uses the lua_boxpointer macro which creates a new
userdata (with lua_newuserdata) that contains a single pointer, and stores
the FILE* in it. the current prototype of lua_newuserdata(L,size) does not
allow for what I am thinking about, but what if it was changed to
lua_newuserdata(L,p,size) ?
When p is NULL and size is not, lua creates the memory block as before. When
p is non-NULL and size is 0, lua stores p directly in the userdata. If both
are 0 or non-0, an assertion is raised.
In the first case, the implementor must have its __gc metamethod return
true, and in the second case it must return false.

I don't know if I am too clear about this, so feel free to tell me what's
wrong about my reasoning :-)