From 46aa1649f9e37b55279b883c59c44def7de55249 Mon Sep 17 00:00:00 2001 From: espkk Date: Fri, 10 Apr 2026 01:22:20 +0100 Subject: [PATCH 1/2] Fix env for lua5.1/luajit --- .../script/backend/worker/eval/readonly.lua | 6 ++++++ .../script/backend/worker/eval/readwrite.lua | 6 ++++++ extension/script/backend/worker/variables.lua | 15 +++++++++++++-- src/luadebug/rdebug_visitor.cpp | 14 ++++++++++++++ src/luadebug/util/refvalue.cpp | 19 +++++++++++++++++++ src/luadebug/util/refvalue.h | 6 +++++- 6 files changed, 63 insertions(+), 3 deletions(-) diff --git a/extension/script/backend/worker/eval/readonly.lua b/extension/script/backend/worker/eval/readonly.lua index 49e01d45..ecce35cd 100644 --- a/extension/script/backend/worker/eval/readonly.lua +++ b/extension/script/backend/worker/eval/readonly.lua @@ -33,6 +33,9 @@ do i = i + 1 end end +if not env and getfenv then + env = getfenv(f) +end do local i = 1 while true do @@ -76,6 +79,9 @@ end local compiled = env and assert(_load(full_source, '=(EVAL)', "t", env)) or assert(_load(full_source, '=(EVAL)')) +if env and setfenv then + setfenv(compiled, env) +end local func = compiled() do local i = 1 diff --git a/extension/script/backend/worker/eval/readwrite.lua b/extension/script/backend/worker/eval/readwrite.lua index 4073c181..12b41473 100644 --- a/extension/script/backend/worker/eval/readwrite.lua +++ b/extension/script/backend/worker/eval/readwrite.lua @@ -42,6 +42,9 @@ do i = i + 1 end end +if not env and getfenv then + env = getfenv(f) +end do local i = 1 while true do @@ -90,6 +93,9 @@ end local compiled = env and assert(_load(full_source, '=(EVAL)', "t", env)) or assert(_load(full_source, '=(EVAL)')) +if env and setfenv then + setfenv(compiled, env) +end local func, update = compiled() local found = {} do diff --git a/extension/script/backend/worker/variables.lua b/extension/script/backend/worker/variables.lua index a42a4874..f2a22890 100644 --- a/extension/script/backend/worker/variables.lua +++ b/extension/script/backend/worker/variables.lua @@ -146,8 +146,19 @@ function special_has.Global(frameId) rdebug.getinfo(frameId, "f", info) local eval, value = rdebug.getupvaluev(info.func, 1) if eval ~= "_ENV" then - eval = "_G" - value = rdebug._G + if LUAVERSION == 51 then + local fenv = rdebug.getfenv(info.func) + if fenv and not rdebug.equal(fenv, rdebug._G) then + eval = nil + value = fenv + else + eval = "_G" + value = rdebug._G + end + else + eval = "_G" + value = rdebug._G + end end if eval == "_G" and globalCache._G then local t = globalCache._G diff --git a/src/luadebug/rdebug_visitor.cpp b/src/luadebug/rdebug_visitor.cpp index a0cd45fe..739e6dad 100644 --- a/src/luadebug/rdebug_visitor.cpp +++ b/src/luadebug/rdebug_visitor.cpp @@ -792,6 +792,19 @@ namespace luadebug::visitor { return 2; } + static int visitor_getfenv(luadbg_State* L, lua_State* hL, protected_area& area) { +#if LUA_VERSION_NUM == 501 + if (!copy_from_dbg(L, hL, area, 1, LUADBG_TFUNCTION)) { + return 0; + } + lua_pop(hL, 1); + refvalue::create(L, 1, refvalue::FENV {}); + return 1; +#else + return 0; +#endif + } + template static int visitor_getmetatable(luadbg_State* L, lua_State* hL, protected_area& area) { area.check_client_stack(2); @@ -1120,6 +1133,7 @@ namespace luadebug::visitor { { "getlocalv", protected_call> }, { "getupvalue", protected_call }, { "getupvaluev", protected_call> }, + { "getfenv", protected_call }, { "getmetatable", protected_call }, { "getmetatablev", protected_call> }, { "getuservalue", protected_call }, diff --git a/src/luadebug/util/refvalue.cpp b/src/luadebug/util/refvalue.cpp index 6053e87f..ec644a87 100644 --- a/src/luadebug/util/refvalue.cpp +++ b/src/luadebug/util/refvalue.cpp @@ -328,6 +328,25 @@ namespace luadebug::refvalue { } } + template <> + int eval(FENV& v, lua_State* hL, value* parent) { + int t = eval(parent, hL); + if (t == LUA_TNONE) + return LUA_TNONE; + if (t != LUA_TFUNCTION) { + lua_pop(hL, 1); + return LUA_TNONE; + } +#if LUA_VERSION_NUM == 501 + lua_getfenv(hL, -1); + lua_replace(hL, -2); + return lua_type(hL, -1); +#else + lua_pop(hL, 1); + return LUA_TNONE; +#endif + } + int eval(value* v, lua_State* hL) { return visit([hL, v](auto&& arg) { return eval(arg, hL, v + 1); }, *v); } diff --git a/src/luadebug/util/refvalue.h b/src/luadebug/util/refvalue.h index 7d77f371..d2902c6e 100644 --- a/src/luadebug/util/refvalue.h +++ b/src/luadebug/util/refvalue.h @@ -53,6 +53,7 @@ namespace luadebug::refvalue { struct USERDATA_VAL { unsigned int index; }; + struct FENV {}; using value = variant< FRAME_LOCAL, FRAME_FUNC, @@ -66,7 +67,8 @@ namespace luadebug::refvalue { TABLE_HASH_KEY, TABLE_HASH_VAL, USERDATA_KEY, - USERDATA_VAL>; + USERDATA_VAL, + FENV>; static_assert(std::is_trivially_copyable_v); template @@ -102,6 +104,8 @@ namespace luadebug::refvalue { struct allow_as_child : public std::true_type {}; template <> struct allow_as_child : public std::true_type {}; + template <> + struct allow_as_child : public std::true_type {}; int eval(value* v, lua_State* hL); bool assign(value* v, lua_State* hL); From c4aa9b7a4440a68df874f233a3c68cda1d0231c8 Mon Sep 17 00:00:00 2001 From: espkk Date: Fri, 10 Apr 2026 21:03:58 +0100 Subject: [PATCH 2/2] Address clanker --- extension/script/backend/worker/variables.lua | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/extension/script/backend/worker/variables.lua b/extension/script/backend/worker/variables.lua index f2a22890..d8d472af 100644 --- a/extension/script/backend/worker/variables.lua +++ b/extension/script/backend/worker/variables.lua @@ -146,18 +146,14 @@ function special_has.Global(frameId) rdebug.getinfo(frameId, "f", info) local eval, value = rdebug.getupvaluev(info.func, 1) if eval ~= "_ENV" then + eval = "_G" + value = rdebug._G if LUAVERSION == 51 then local fenv = rdebug.getfenv(info.func) if fenv and not rdebug.equal(fenv, rdebug._G) then eval = nil value = fenv - else - eval = "_G" - value = rdebug._G end - else - eval = "_G" - value = rdebug._G end end if eval == "_G" and globalCache._G then