refactor(lua): generate separate environments for script
This commit is contained in:
parent
e28436b76c
commit
133ca0bb5e
4 changed files with 37 additions and 22 deletions
|
@ -38,25 +38,6 @@ LuaSignalConnection::~LuaSignalConnection() {
|
||||||
luaL_unref(state, LUA_REGISTRYINDEX, thread);
|
luaL_unref(state, LUA_REGISTRYINDEX, thread);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0
|
|
||||||
static void stackdump(lua_State* L) {
|
|
||||||
printf("%d\n", lua_gettop(L));
|
|
||||||
fflush(stdout);
|
|
||||||
lua_getfield(L, LUA_GLOBALSINDEX, "tostring");
|
|
||||||
for (int i = lua_gettop(L)-1; i >= 1; i--) {
|
|
||||||
lua_pushvalue(L, -1);
|
|
||||||
lua_pushvalue(L, i);
|
|
||||||
lua_call(L, 1, 1);
|
|
||||||
const char* str = lua_tostring(L, -1);
|
|
||||||
lua_pop(L, 1);
|
|
||||||
printf("%s: %s\n", lua_typename(L, lua_type(L, i)), str);
|
|
||||||
}
|
|
||||||
lua_pop(L, 1);
|
|
||||||
printf("\n\n");
|
|
||||||
fflush(stdout);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
void LuaSignalConnection::Call(std::vector<Variant> args) {
|
void LuaSignalConnection::Call(std::vector<Variant> args) {
|
||||||
lua_State* thread = lua_newthread(state);
|
lua_State* thread = lua_newthread(state);
|
||||||
|
|
||||||
|
|
|
@ -31,13 +31,22 @@ void Script::Run() {
|
||||||
this->thread = lua_newthread(L);
|
this->thread = lua_newthread(L);
|
||||||
lua_State* Lt = thread;
|
lua_State* Lt = thread;
|
||||||
|
|
||||||
|
lua_pushthread(Lt); // Push thread for later*
|
||||||
|
|
||||||
// Initialize script globals
|
// Initialize script globals
|
||||||
lua_getglobal(Lt, "_G");
|
scriptContext->NewEnvironment(Lt); // Pushes envtable, metatable
|
||||||
|
|
||||||
|
// Set script in metatable source
|
||||||
|
InstanceRef(shared_from_this()).PushLuaValue(Lt);
|
||||||
|
lua_setfield(Lt, -2, "source");
|
||||||
|
|
||||||
|
lua_pop(Lt, 1); // Pop metatable
|
||||||
|
|
||||||
InstanceRef(shared_from_this()).PushLuaValue(Lt);
|
InstanceRef(shared_from_this()).PushLuaValue(Lt);
|
||||||
lua_setfield(Lt, -2, "script");
|
lua_setfield(Lt, -2, "script");
|
||||||
|
|
||||||
lua_pop(Lt, 1); // _G
|
lua_setfenv(Lt, -2); // *Set env of current thread
|
||||||
|
lua_pop(Lt, 1); // Pop thread
|
||||||
|
|
||||||
// Push wrapper as thread function
|
// Push wrapper as thread function
|
||||||
lua_getfield(Lt, LUA_REGISTRYINDEX, "LuaPCallWrapper");
|
lua_getfield(Lt, LUA_REGISTRYINDEX, "LuaPCallWrapper");
|
||||||
|
|
|
@ -17,13 +17,14 @@ int g_wait(lua_State*);
|
||||||
int g_delay(lua_State*);
|
int g_delay(lua_State*);
|
||||||
static int g_print(lua_State*);
|
static int g_print(lua_State*);
|
||||||
static int g_require(lua_State*);
|
static int g_require(lua_State*);
|
||||||
static const struct luaL_Reg luaglobals [] = {
|
static const luaL_Reg luaglobals [] = {
|
||||||
{"print", g_print},
|
{"print", g_print},
|
||||||
{"require", g_require},
|
{"require", g_require},
|
||||||
{NULL, NULL} /* end of array */
|
{NULL, NULL} /* end of array */
|
||||||
};
|
};
|
||||||
|
|
||||||
std::string unsafe_globals[] = {
|
std::string unsafe_globals[] = {
|
||||||
|
// Todo implement our own "safe" setfenv/getfenv
|
||||||
"loadfile", "loadstring", "load", "dofile", "getfenv", "setfenv"
|
"loadfile", "loadstring", "load", "dofile", "getfenv", "setfenv"
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -161,6 +162,27 @@ void ScriptContext::RunSleepingThreads() {
|
||||||
schedTime = tu_clock_micros() - startTime;
|
schedTime = tu_clock_micros() - startTime;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ScriptContext::NewEnvironment(lua_State* L) {
|
||||||
|
lua_newtable(L); // Env table
|
||||||
|
lua_newtable(L); // Metatable
|
||||||
|
|
||||||
|
// Push __index
|
||||||
|
lua_pushvalue(L, LUA_GLOBALSINDEX);
|
||||||
|
lua_setfield(L, -2, "__index");
|
||||||
|
|
||||||
|
// Push __metatable
|
||||||
|
lua_pushstring(L, "metatable is locked");
|
||||||
|
lua_setfield(L, -2, "__metatable");
|
||||||
|
|
||||||
|
// Copy metatable and set the env table's metatable
|
||||||
|
lua_pushvalue(L, -1);
|
||||||
|
lua_setmetatable(L, -3);
|
||||||
|
|
||||||
|
// Remainder on stack:
|
||||||
|
// 1. Env table
|
||||||
|
// 2. Metatable
|
||||||
|
}
|
||||||
|
|
||||||
// https://www.lua.org/source/5.1/lbaselib.c.html
|
// https://www.lua.org/source/5.1/lbaselib.c.html
|
||||||
static int g_print(lua_State* L) {
|
static int g_print(lua_State* L) {
|
||||||
std::string buf;
|
std::string buf;
|
||||||
|
|
|
@ -32,5 +32,8 @@ public:
|
||||||
void PushThreadSleep(lua_State* thread, float delay);
|
void PushThreadSleep(lua_State* thread, float delay);
|
||||||
void RunSleepingThreads();
|
void RunSleepingThreads();
|
||||||
|
|
||||||
|
// Generates an environment with a metatable and pushes it both the env table and metatable in order onto the stack
|
||||||
|
void NewEnvironment(lua_State* state);
|
||||||
|
|
||||||
static inline std::shared_ptr<Instance> Create() { return std::make_shared<ScriptContext>(); };
|
static inline std::shared_ptr<Instance> Create() { return std::make_shared<ScriptContext>(); };
|
||||||
};
|
};
|
Loading…
Add table
Reference in a new issue