[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
- Subject: Re: [BUG] Re: A luaL_Buffer question
- From: Dirk Laurie <dirk.laurie@...>
- Date: Thu, 2 Nov 2017 14:53:19 +0200
2017-11-02 12:54 GMT+02:00 Viacheslav Usov <via.usov@gmail.com>:
> On Thu, Nov 2, 2017 at 8:41 AM, Marc Balmer <marc@msys.ch> wrote:
>
>> Is it possible to create a luaL_Buffer over several calls to Lua
>> functions? E.g. like in the following pseudo code:
>
> [...]
>
>> Or must all buffer operations be finished when I return from C code?
> I am unsure why such a dangerous facility is present, but I think that its
> dangers should be stressed by stronger language. The problem is that the
> crash happens only when large strings are stuffed into the buffer, which is
> a perfect ingredient for "it works when I test it, but it crashes randomly
> in production, and no one knows why".
It is there for greater efficiency.
> I think it can also be made less dangerous by using a reference to the
> userdatum rather than the top of the stack, but frankly, I think this is
> something that should only be used by Lua itself and its public use
> deprecated.
Oh, that is overstating the case. The public (or at least that section
of it that can write code in the Lua C API) is not so delicate.
What I envisaged in my earlier reply is in fact quite easy, almost
trivial. See attachment. (Lua 5.3).
/* buffer.c © Dirk Laurie 2017 MIT license like Lua
Compile with: cc -shared buffer.c -o buffer.so
If you get a message containing the hint "recompile with -fPIC"., obey it.
I.e.
cc -shared buffer.c -fPIC -o buffer.so
Exercise for the reader: add a Lua front-end that allows object-oriented
calls. i.e. buf:append(item) instead of buffer.append(buf,item) etc.
The metatable is already there. */
#include <lua.h>
#include <lualib.h>
#include <lauxlib.h>
static int buffer_new (lua_State *L) {
lua_newuserdata(L,sizeof(luaL_Buffer));
luaL_buffinit(L, (luaL_Buffer*) lua_topointer(L,-1));
luaL_setmetatable(L,"Buffer");
return 1;
}
static int buffer_flush (lua_State *L) {
luaL_Buffer* buf = (luaL_Buffer*) luaL_checkudata(L,1,"Buffer");
luaL_pushresult(buf);
return 1;
}
static int buffer_append (lua_State *L) {
luaL_Buffer* buf = (luaL_Buffer*) luaL_checkudata(L,1,"Buffer");
luaL_addvalue(buf);
return 0;
}
static const luaL_Reg buffer_funcs[] = {
{"new", buffer_new},
{"flush", buffer_flush},
{"append", buffer_append},
{NULL, NULL}
};
LUAMOD_API int luaopen_buffer (lua_State *L) {
luaL_newmetatable (L, "Buffer");
luaL_newlib(L, buffer_funcs);
return 1;
}