Date Tags lua

I just implemented a script-cache for MySQL Proxy and had to learn a bit more about lua internals. As a result I wrote two functions which are generic enough for general consumption:

  • luaL_loadfile_factory()
  • luaL_loadstring_factory()

They also show how to write a lua_Reader for lua_load().

The #lua channel on freenode was a great help, as always.

LUA provide several loaders:

  • luaL_loadstring
  • luaL_loadbuffer
  • luaL_loadfile

and you can create your own if you have to.

Now, why the need for a new loader ?

The proxy we have

  • a global scope caches the scripts
  • this cache reloads the scripts if they changed on disk
  • each thread executes the same script
  • each thread has its own script-scope

which looks like:

/* puts the script at the top */
lua_cache_get_script(global_L. scriptname);

L = lua_newthread(global_L);
lua_xmove(global_L, L, 1);
...
lua_pcall(L, ...);

To set the script-scope we use lua_setfenv(), but we can't run it against the script itself as the script is shared between all threads. Setting the environment of the script would change it for all threads.

The solution is using a function-factory

return function()
  ... script ...
end

to create a function I can assign a unique environment to.

The loader automaticly adds the header and trailer to the scripts are load-time.

Instead of the normal load-procedure:

luaL_loadfile(L, scriptname);
lua_newtable(L);
...
lua_setfenv(L, -2);

lua_pcall(L, 0, 0, 0);

you write:

luaL_loadfile_factory(L, scriptname);
/* this function can be cached */

lua_pcall(L, 0, 1, 0); /* returns a function with a clean enviroment */

lua_newtable(L);
...
lua_setfenv(L, -2);

lua_pcall(L, 0, 0, 0);

Comments

Enable javascript to load comments.