lua-users home
lua-l archive

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

2017-11-02 12:54 GMT+02:00 Viacheslav Usov <>:
> On Thu, Nov 2, 2017 at 8:41 AM, Marc Balmer <> 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
   If you get a message containing the hint "recompile with -fPIC"., obey it.

      cc -shared buffer.c -fPIC -o 

   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) {
  luaL_buffinit(L, (luaL_Buffer*) lua_topointer(L,-1));
  return 1;

static int buffer_flush (lua_State *L) {
  luaL_Buffer* buf = (luaL_Buffer*) luaL_checkudata(L,1,"Buffer");
  return 1;   

static int buffer_append (lua_State *L) {
  luaL_Buffer* buf = (luaL_Buffer*) luaL_checkudata(L,1,"Buffer");
  return 0; 

static const luaL_Reg buffer_funcs[] = {
  {"new", buffer_new},
  {"flush", buffer_flush},
  {"append", buffer_append},

LUAMOD_API int luaopen_buffer (lua_State *L) {
  luaL_newmetatable (L, "Buffer");
  luaL_newlib(L, buffer_funcs);
  return 1;