[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
- Subject: Re: multiple global contexts
- From: Peter Shook <pshook@...>
- Date: Mon, 23 Jun 2003 08:02:30 -0400
Dylan Cuthbert wrote:
I may have read the documentation wrong, but I don't like the way lua lets
all lua co-routines/functions have access to the global scope.
Is there a way to have multiple global scopes, so I don't have to worry
about script writers breaking other people's data or accessing stuff they
shouldn't? I'd like to keep these "global" scopes local to each object (and
have multiple coroutines running within the same "space" on an object).
Also, if this is possible, what kind of overhead (memory footprint/creation
time) does the lua_state structure have? (I presume I'll need multiples of
these)
Hi Dylan,
The lua_State structure is 96 bytes when compiled with gcc on a PC.
You can use lua_replace(L, LUA_GLOBALSINDEX);
to change the globals for a thread.
Here is an example:
#include "lua.h"
#include "lauxlib.h"
#include "lualib.h"
static int report (lua_State *L, int status) {
const char *msg;
if (status) {
msg = lua_tostring(L, -1);
if (msg == NULL) msg = "(error with no message)";
fprintf(stderr, "%s\n", msg);
lua_pop(L, 1);
}
return status;
}
static int fixglobals (lua_State *L) {
lua_newtable(L); /* new table for globals */
lua_newtable(L); /* metatable for new globals */
lua_pushliteral(L, "__index");
lua_pushvalue(L, LUA_GLOBALSINDEX); /* __index tries old common
globals */
lua_settable(L, -3);
lua_setmetatable(L, -2);
lua_replace(L, LUA_GLOBALSINDEX);
}
int main(int argc, char *argv[])
{
lua_State *L = lua_open();
luaopen_base(L);
luaopen_table(L);
luaopen_io(L);
luaopen_string(L);
luaopen_math(L);
luaopen_debug(L);
if(argc>2) {
int status, i;
lua_State *C1 = lua_newthread(L);
lua_State *C2 = lua_newthread(L);
fixglobals(C1);
lua_pushliteral(C1, "c1");
lua_setglobal(C1, "name");
lua_pushnumber(C1, 2);
lua_setglobal(C1, "N");
fixglobals(C2);
lua_pushliteral(C2, "c2");
lua_setglobal(C2, "name");
lua_pushnumber(C2, 3);
lua_setglobal(C2, "N");
printf("loading %s\n", argv[1]);
if (report(C1, luaL_loadfile(C1, argv[1]) )) exit(1);
printf("loading %s\n", argv[2]);
if (report(C2, luaL_loadfile(C2, argv[2]) )) exit(2);
printf("start looping\n");
for (i=0; i<10; i++) {
if (report(C1, lua_resume(C1, 0) )) exit(3);
if (report(C2, lua_resume(C2, 0) )) exit(4);
printf("i = %d\n", i);
}
}
lua_setgcthreshold(L, 0); /* collected garbage */
lua_close(L);
return 0;
}
$ gcc -g -o test coroutine.c -Llib -llua -llualib
$ cat c2.lua
print('env', name, getfenv())
not_dead_yet = true
while not_dead_yet do
for i = 1,N do
print(name, i)
coroutine.yield(i)
end
end
$ ./test c2.lua c2.lua
loading c2.lua
loading c2.lua
start looping
env c1 table: 0xa045980
c1 1
env c2 table: 0xa045a60
c2 1
i = 0
c1 2
c2 2
i = 1
c1 1
c2 3
i = 2
c1 2
c2 1
i = 3
c1 1
c2 2
i = 4
c1 2
c2 3
i = 5
c1 1
c2 1
i = 6
c1 2
c2 2
i = 7
c1 1
c2 3
i = 8
c1 2
c2 1
i = 9