[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
- Subject: Sandboxing scripts, luaL_openlibs, and require
- From: Guy Junk <guyjunkaccount@...>
- Date: Thu, 14 May 2009 21:39:34 -0300
I am developing a game using C++ where the logic of different entities
are controlled by Lua scripts. So, I'd have a collection of scripts
that each have a standard set of functions like "nextAction", as well
as any internal state (most likely in the form of global variables)
the C++ side doesn't and shouldn't know about.
Since I don't want my scripts overwriting each other, some form of
sandboxing is in order. The behaviour I want can be achieved by having
multiple lua_State objects for each script instance; i.e. each
script-controlled entity has its own lua_State. I heard that this was
wasteful though, so I've been looking at threads and environment
tables.
So far I've been trying to use lua threads. I start off by creating my
main lua_State. For every script I load, I create a new thread:
-----------------------------------------------------------------------
lua_State *scriptThread = lua_newthread(mainLuaState);
lua_newtable(scriptThread);
lua_replace(scriptThread, LUA_GLOBALSINDEX );
//lua_setfenv(scriptThread, 1); // Doesn't seem to work
luaL_openlibs(scriptThread); // I could have loaded this once in the
// main Lua state and then manipulated the
// current thread's metatable, but I want
// to illustrate a bug here later.
if (luaL_dofile(scriptThread, path.c_str()))
{
throw runtime_error("Could not load file '" + path + "': "
+ lua_tostring(scriptThread, -1));
}
-----------------------------------------------------------------------
Whenever I need to call a function for a particular script instance, I
access its thread. This seems to work for running general script
logic. However, including libraries seems to only work for the first
script I load.
The call to luaL_openlibs only works for the first script I load. If I
have print() in two scripts and I run those scripts, only the first
script I loaded and ran will recognize the print() while the second
script will think it's a nil value.
Similarly, require doesn't work for scripts that weren't loaded first.
I made two scripts that call a function inside a common Lua file (i.e.
they both require() this file). The first script to be loaded is able
to call this function, while the second thinks the function is a nil
value.