lua-users home
lua-l archive

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


> On occasion I have used lua_newuserdata as your luaL_prepstring and then
> lua_pushstring as your lua_pushprepstring. This does involve double allocation
> and copy but at least the boring parts (allocation and deallocation when an
> error occurs) are handled by Lua.

This is indeed a good trick when you do not want to bother with error checking.
In my use case I am more concerned about "performances", that is why I am looking for ways to prevent double mallocs/memcpy.

BTW I forgot to give an example of my use case:
Imagine you have a third party C API that provides a reader as: read(Object* object, char* buffer) that read some object and write into the buffer.
The easiest way to do it with standard lua API is: (pseudo C code)

...
char* buffer = malloc(objectsize);
read(object, buffer);
lua_pushlstring(L, buffer, objectsize); // can lua_pushlstring "thow" an error? (malloc failed)
                                        // in that case setjmp/longjmp must be used to prevent
                                        // memory leak here.
free(buffer);
return 1;

=> 2 mallocs (one inside Lua), 1 memcpy




Alternative1 (not my case): if you know that objectsize < LUAL_BUFFERSIZE
...
luaL_Buffer buffer;
luaL_buffinit(L, &buffer);
char* b = luaL_prepbuffer(&buffer);
read(object, b);
luaL_addsize(&buffer, objectsize);
luaL_pushresult(&buffer);
return 1;

=> 1 malloc (inside Lua), 1 memcpy



Alternative2 (my proposal):
...
char* b = lua_prepstring(L, objectsize);
read(object, b);
lua_pushprepstring(b);
return 1;

=> 1 malloc (in prepstring), 0 memcpy (pushprepstring works in place)