Skip to content

Commit

Permalink
Lua51 support vararg (#257)
Browse files Browse the repository at this point in the history
  • Loading branch information
fesily committed May 5, 2023
1 parent c990072 commit b21a242
Show file tree
Hide file tree
Showing 7 changed files with 103 additions and 22 deletions.
19 changes: 7 additions & 12 deletions extension/script/backend/worker/variables.lua
Original file line number Diff line number Diff line change
Expand Up @@ -107,13 +107,11 @@ end
local special_has = {}

function special_has.Parameter(frameId)
if LUAVERSION >= 52 then
rdebug.getinfo(frameId, "u", info)
if info.nparams > 0 then
return true
end
return rdebug.getlocalv(frameId, -1) ~= nil
rdebug.getinfo(frameId, "u", info)
if info.nparams > 0 then
return true
end
return rdebug.getlocalv(frameId, -1) ~= nil
end

function special_has.Local(frameId)
Expand Down Expand Up @@ -941,11 +939,9 @@ function special_extand.Local(varRef)
local tempVar = {}
local vars = {}
local i = 1
if LUAVERSION >= 52 then
rdebug.getinfo(frameId, "u", info)
if info.nparams > 0 then
i = i + info.nparams
end
rdebug.getinfo(frameId, "u", info)
if info.nparams > 0 then
i = i + info.nparams
end
while true do
local name, value = rdebug.getlocalv(frameId, i)
Expand Down Expand Up @@ -1009,7 +1005,6 @@ function special_extand.Parameter(varRef)
local frameId = varRef.frameId
local vars = {}

assert(LUAVERSION >= 52)
rdebug.getinfo(frameId, "u", info)
if info.nparams > 0 then
for i = 1, info.nparams do
Expand Down
15 changes: 12 additions & 3 deletions src/luadebug/compat/5x/callinfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,7 @@ CallInfo* lua_getcallinfo(lua_State* L) {
return L->ci;
}

Proto* lua_ci2proto(CallInfo* ci) {
StkId func = LUA_STKID(ci->func);
inline Proto* func2proto(StkId func) {
#if LUA_VERSION_NUM >= 502
if (!ttisLclosure(s2v(func))) {
return 0;
Expand All @@ -31,10 +30,20 @@ Proto* lua_ci2proto(CallInfo* ci) {
#endif
}

CallInfo* lua_debug2ci(lua_State* L, lua_Debug* ar) {
Proto* lua_ci2proto(CallInfo* ci) {
StkId func = LUA_STKID(ci->func);
return func2proto(func);
}

CallInfo* lua_debug2ci(lua_State* L, const lua_Debug* ar) {
#if LUA_VERSION_NUM >= 502
return ar->i_ci;
#else
return L->base_ci + ar->i_ci;
#endif
}

Proto* lua_getproto(lua_State* L, int idx) {
auto func = LUA_STKID(L->top) + idx;
return func2proto(func);
}
30 changes: 30 additions & 0 deletions src/luadebug/compat/5x/common.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,35 @@
#include "compat/internal.h"
#include "compat/lua.h"

const void* lua_tocfunction_pointer(lua_State* L, int idx) {
return (const void*)lua_tocfunction(L, idx);
}
#if LUA_VERSION_NUM == 501
# include <lobject.h>
# include <lstate.h>
namespace lua {
const char* lua_getlocal(lua_State* L, const lua_Debug* ar, int n) {
if (n < 0) {
auto ci = lua_debug2ci(L, ar);
auto proto = lua_ci2proto(ci);
if (!proto) {
return nullptr;
}

n = -n;
auto nparams = proto->numparams;
if (n >= ci->base - ci->func - nparams) {
return nullptr; // no such vararg
}
else {
auto o = ci->func + nparams + n;
setobj2s(L, L->top, o);
api_incr_top(L);
return "(*vararg)";
}
return nullptr;
}
return ::lua_getlocal(L, ar, n);
}
}
#endif
11 changes: 10 additions & 1 deletion src/luadebug/compat/internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,22 @@ struct CallInfo;
struct Proto;
#endif

Proto* lua_getproto(lua_State* L, int idx);
CallInfo* lua_getcallinfo(lua_State* L);
Proto* lua_ci2proto(CallInfo* ci);
CallInfo* lua_debug2ci(lua_State* L, lua_Debug* ar);
CallInfo* lua_debug2ci(lua_State* L, const lua_Debug* ar);

#ifdef LUAJIT_VERSION
int lua_isluafunc(lua_State* L, lua_Debug* ar);
#endif

int lua_stacklevel(lua_State* L);
lua_State* lua_getmainthread(lua_State* L);

#if LUA_VERSION_NUM == 501 && !defined(LUAJIT_VERSION)
# define api_incr_top(L) \
{ \
api_check(L, L->top < L->ci->top); \
L->top++; \
}
#endif
18 changes: 15 additions & 3 deletions src/luadebug/compat/jit/callinfo.cpp
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@

#include <lj_arch.h>
#include <lj_debug.h>
#include <lj_frame.h>
#include <lj_obj.h>

#include "compat/internal.h"

extern TValue* index2adr(lua_State* L, int idx);

static cTValue* debug_frame(lua_State* L, int level, int* size) {
cTValue *frame, *nextframe, *bot = tvref(L->stack) + LJ_FR2;
/* Traverse frames backwards. */
Expand Down Expand Up @@ -34,14 +37,23 @@ CallInfo* lua_getcallinfo(lua_State* L) {
return const_cast<CallInfo*>(debug_frame(L, 0, &size));
}

Proto* lua_ci2proto(CallInfo* ci) {
GCfunc* func = frame_func(ci);
inline Proto* func2proto(GCfunc* func) {
if (!isluafunc(func))
return 0;
return funcproto(func);
}

CallInfo* lua_debug2ci(lua_State* L, lua_Debug* ar) {
Proto* lua_getproto(lua_State* L, int idx) {
GCfunc* func = funcV(index2adr(L, idx));
return func2proto(func);
}

Proto* lua_ci2proto(CallInfo* ci) {
GCfunc* func = frame_func(ci);
return func2proto(func);
}

CallInfo* lua_debug2ci(lua_State* L, const lua_Debug* ar) {
uint32_t offset = (uint32_t)ar->i_ci & 0xffff;
return tvref(L->stack) + offset;
}
Expand Down
6 changes: 6 additions & 0 deletions src/luadebug/compat/lua.h
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,12 @@ namespace lua {
LUACOMPAT_DEF(rawgetp)
LUACOMPAT_DEF(getglobal)
LUACOMPAT_DEF(getfield)

#if LUA_VERSION_NUM == 501 && !defined(LUAJIT_VERSION)
const char* lua_getlocal(lua_State* L, const lua_Debug* ar, int n);
#else
constexpr auto lua_getlocal = ::lua_getlocal;
#endif
}

#if LUA_VERSION_NUM == 501
Expand Down
26 changes: 23 additions & 3 deletions src/luadebug/rdebug_visitor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@

#ifdef LUAJIT_VERSION
# include <lj_cdata.h>
# include <lj_debug.h>
#else
# include <lstate.h>
#endif
Expand Down Expand Up @@ -214,7 +215,7 @@ namespace luadebug::visitor {
return 0;
}
area.check_client_stack(1);
const char* name = lua_getlocal(hL, &ar, n);
const char* name = lua::lua_getlocal(hL, &ar, n);
if (name == NULL)
return 0;
if (!getref && copy_to_dbg(hL, L) != LUA_TNONE) {
Expand Down Expand Up @@ -629,6 +630,9 @@ namespace luadebug::visitor {
#ifdef LUAJIT_VERSION
bool hasS = false;
#endif
[[maybe_unused]] Proto* proto = nullptr;
[[maybe_unused]] bool needProto = false;

for (const char* what = options.data(); *what; what++) {
switch (*what) {
case 'S':
Expand All @@ -647,10 +651,13 @@ namespace luadebug::visitor {
size += 1;
hasF = true;
break;
#if LUA_VERSION_NUM >= 502
case 'u':
size += 1;
#if LUA_VERSION_NUM == 501
needProto = true;
#endif
break;
#if LUA_VERSION_NUM >= 502
case 't':
size += 1;
break;
Expand All @@ -677,6 +684,9 @@ namespace luadebug::visitor {
return 0;
if (lua_getinfo(hL, options.data(), &ar) == 0)
return 0;
if (needProto) {
proto = lua_ci2proto(lua_debug2ci(hL, &ar));
}
if (hasF) lua_pop(hL, 1);
break;
case LUADBG_TUSERDATA: {
Expand All @@ -689,6 +699,9 @@ namespace luadebug::visitor {
char what[8];
what[0] = '>';
strcpy(what + 1, options.data());
if (needProto) {
proto = lua_getproto(hL, -1);
}
if (lua_getinfo(hL, what, &ar) == 0) {
return 0;
}
Expand Down Expand Up @@ -739,11 +752,18 @@ namespace luadebug::visitor {
refvalue::create(L, refvalue::FRAME_FUNC { (uint16_t)frame });
luadbg_setfield(L, 3, "func");
break;
#if LUA_VERSION_NUM >= 502
case 'u':
#if LUA_VERSION_NUM >= 502
luadbg_pushinteger(L, ar.nparams);
luadbg_setfield(L, 3, "nparams");
#else
if (proto) {
luadbg_pushinteger(L, proto->numparams);
luadbg_setfield(L, 3, "nparams");
}
#endif
break;
#if LUA_VERSION_NUM >= 502
case 't':
luadbg_pushboolean(L, ar.istailcall ? 1 : 0);
luadbg_setfield(L, 3, "istailcall");
Expand Down

0 comments on commit b21a242

Please sign in to comment.