cleanup global environment (_ENV* variables)

This commit is contained in:
MihailRis 2026-04-27 02:16:24 +03:00
parent 629f672d38
commit ad1d7477ad
4 changed files with 54 additions and 37 deletions

View file

@ -1010,8 +1010,9 @@ static int l_gui_get_env(lua::State* L) {
"document '" + std::string(name) + "' not found"
);
}
lua::getglobal(L, lua::env_name(*doc->getEnvironment()));
return 1;
return lua::getregistry(
L, lua::ENVS_TABLE, lua::env_name(*doc->getEnvironment())
);
}
static int l_gui_str(lua::State* L) {

View file

@ -122,15 +122,17 @@ void lua::init_state(State* L, StateType stateType) {
remove_lib_funcs(L, "os", removed_os);
create_libs(L, stateType);
pushglobals(L);
setglobal(L, env_name(0));
createtable(L, 0, 0);
setregistry(L, LAMBDAS_TABLE);
createtable(L, 0, 0);
setregistry(L, CHUNKS_TABLE);
createtable(L, 0, 0);
pushglobals(L);
setfield(L, env_name(0));
setregistry(L, ENVS_TABLE);
initialize_libs_extends(L);
newusertype<LuaHeightmap>(L);

View file

@ -8,7 +8,7 @@
using namespace lua;
static int nextEnvironment = 1;
static int next_environment = 1;
std::unordered_map<std::type_index, std::string> lua::usertypeNames;
@ -20,7 +20,7 @@ int lua::userdata_destructor(lua::State* L) {
}
std::string lua::env_name(int env) {
return "_ENV" + util::mangleid(env);
return std::to_string(env);
}
int lua::pushvalue(State* L, const dv::value& value) {
@ -317,8 +317,16 @@ scripting::common_func lua::create_lambda_nothrow(State* L) {
};
}
static void store_env(lua::State* L, int id) {
requireregistry(L, ENVS_TABLE);
pushvalue(L, -2);
lua_remove(L, -3);
setfield(L, env_name(id));
pop(L);
}
int lua::create_environment(State* L, int parent) {
int id = nextEnvironment++;
int id = next_environment++;
// local env = {}
createtable(L, 0, 1);
@ -335,24 +343,22 @@ int lua::create_environment(State* L, int parent) {
setfield(L, "__index");
setmetatable(L);
// envname = env
setglobal(L, env_name(id));
store_env(L, id);
return id;
}
int lua::restore_pack_environment(lua::State* L, const std::string& packid) {
if(!lua::requireregistry(L, lua::PACK_ENVS_TABLE)) {
if(!requireregistry(L, PACK_ENVS_TABLE)) {
return -1;
}
int id = nextEnvironment++;
int id = next_environment++;
if (lua::getfield(L, packid)) {
// envname = env
setglobal(L, env_name(id));
lua::pop(L);
if (getfield(L, packid)) {
store_env(L, id);
pop(L);
return id;
}
lua::pop(L);
pop(L);
return -1;
}
@ -361,5 +367,5 @@ void lua::remove_environment(State* L, int id) {
return;
}
pushnil(L);
setglobal(L, env_name(id));
store_env(L, id);
}

View file

@ -15,6 +15,7 @@ namespace lua {
inline std::string LAMBDAS_TABLE = "$L"; // lambdas storage
inline std::string CHUNKS_TABLE = "$C"; // precompiled lua chunks
inline std::string PACK_ENVS_TABLE = "$P";
inline std::string ENVS_TABLE = "$E";
extern std::unordered_map<std::type_index, std::string> usertypeNames;
int userdata_destructor(lua::State* L);
@ -58,6 +59,16 @@ namespace lua {
}
}
inline bool getregistry(lua::State* L, const std::string& name, const std::string& key) {
requireregistry(L, name);
if (getfield(L, key)) {
lua_remove(L, -2);
return true;
}
pop(L);
return false;
}
inline bool hasglobal(lua::State* L, const std::string& name) {
lua_getglobal(L, name.c_str());
if (isnil(L, -1)) {
@ -550,7 +561,7 @@ namespace lua {
if (luaL_loadbuffer(L, src.c_str(), src.length(), file.c_str())) {
throw luaerror(tostring(L, -1));
}
if (env && getglobal(L, env_name(env))) {
if (env && getregistry(L, ENVS_TABLE, env_name(env))) {
lua_setfenv(L, -2);
}
}
@ -658,10 +669,7 @@ namespace lua {
scripting::common_func create_lambda_nothrow(lua::State*);
inline int pushenv(lua::State* L, int env) {
if (getglobal(L, env_name(env))) {
return 1;
}
return 0;
return getregistry(L, ENVS_TABLE, env_name(env));
}
int create_environment(lua::State*, int parent);
int restore_pack_environment(lua::State*, const std::string& packid);
@ -790,14 +798,14 @@ namespace lua {
inline void read_bytes_from_table(
lua::State* L, int tableIndex, std::vector<ubyte>& bytes
) {
if (!lua::istable(L, tableIndex)) {
if (!istable(L, tableIndex)) {
throw std::runtime_error("table expected");
} else {
size_t size = lua::objlen(L, tableIndex);
size_t size = objlen(L, tableIndex);
for (size_t i = 0; i < size; i++) {
lua::rawgeti(L, i + 1, tableIndex);
const int byte = lua::tointeger(L, -1);
lua::pop(L);
rawgeti(L, i + 1, tableIndex);
const int byte = tointeger(L, -1);
pop(L);
if (byte < 0 || byte > 255) {
throw std::runtime_error(
"invalid byte '" + std::to_string(byte) + "'"
@ -809,11 +817,11 @@ namespace lua {
}
inline int create_bytearray(lua::State* L, const void* bytes, size_t size) {
lua::requireglobal(L, "Bytearray_construct");
lua::pushlstring(
requireglobal(L, "Bytearray_construct");
pushlstring(
L, std::string_view(reinterpret_cast<const char*>(bytes), size)
);
return lua::call(L, 1, 1);
return call(L, 1, 1);
}
inline int create_bytearray(lua::State* L, const std::vector<ubyte>& bytes) {
@ -821,12 +829,12 @@ namespace lua {
}
inline std::string_view bytearray_as_string(lua::State* L, int idx) {
lua::pushvalue(L, idx);
lua::requireglobal(L, "Bytearray_as_string");
lua::pushvalue(L, -2);
lua::call(L, 1, 1);
auto view = lua::tolstring(L, -1);
lua::pop(L, 2);
pushvalue(L, idx);
requireglobal(L, "Bytearray_as_string");
pushvalue(L, -2);
call(L, 1, 1);
auto view = tolstring(L, -1);
pop(L, 2);
return view;
}
}