From 005e38a738a6a6be9e6ad38ef40ffea9d4839d24 Mon Sep 17 00:00:00 2001 From: zhangjiequan Date: Sun, 18 Feb 2024 19:40:31 +0800 Subject: [PATCH] =?UTF-8?q?feat:=E9=80=9A=E8=BF=87=E5=8D=95=E7=BA=AF?= =?UTF-8?q?=E4=BF=AE=E6=94=B9=E8=B0=83=E8=AF=95=E5=99=A8=EF=BC=8C=E5=AE=9E?= =?UTF-8?q?=E7=8E=B0=E9=A1=B9=E7=9B=AE=E4=BE=A7=E8=87=AA=E5=AE=9A=E4=B9=89?= =?UTF-8?q?=E6=98=BE=E7=A4=BA=E5=90=84=E7=A7=8Dlua=E7=B1=BB=E5=9E=8B?= =?UTF-8?q?=E5=80=BC=E7=9A=84=E6=96=B9=E5=BC=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- emmy_core/src/emmy_core.cpp | 1 + .../emmy_debugger/debugger/emmy_debugger.h | 7 ++++ .../debugger/emmy_debugger_lib.h | 3 ++ .../emmy_debugger/debugger/extension_point.h | 4 +++ .../include/emmy_debugger/emmy_facade.h | 1 + emmy_debugger/src/debugger/emmy_debugger.cpp | 33 +++++++++++++++++-- .../src/debugger/emmy_debugger_lib.cpp | 13 ++++++++ .../src/debugger/extension_point.cpp | 14 ++++++-- emmy_debugger/src/emmy_facade.cpp | 10 ++++++ 9 files changed, 80 insertions(+), 6 deletions(-) diff --git a/emmy_core/src/emmy_core.cpp b/emmy_core/src/emmy_core.cpp index d81d981..c27a9c1 100644 --- a/emmy_core/src/emmy_core.cpp +++ b/emmy_core/src/emmy_core.cpp @@ -31,6 +31,7 @@ static const luaL_Reg lib[] = { {"breakHere", breakHere}, {"stop", stop}, {"tcpSharedListen", tcpSharedListen}, + {"registerTypeName", registerTypeName}, {nullptr, nullptr} }; diff --git a/emmy_debugger/include/emmy_debugger/debugger/emmy_debugger.h b/emmy_debugger/include/emmy_debugger/debugger/emmy_debugger.h index 9dd3299..477ab7b 100644 --- a/emmy_debugger/include/emmy_debugger/debugger/emmy_debugger.h +++ b/emmy_debugger/include/emmy_debugger/debugger/emmy_debugger.h @@ -22,6 +22,7 @@ #include #include #include +#include #include "emmy_debugger/api/lua_api.h" #include "hook_state.h" @@ -94,6 +95,8 @@ class Debugger: public std::enable_shared_from_this void ClearVariableArenaRef(); + bool RegisterTypeName(const std::string& typeName, std::string& err); + private: std::shared_ptr FindBreakPoint(lua_Debug* ar); std::shared_ptr FindBreakPoint(const std::string& file, int line); @@ -112,6 +115,8 @@ class Debugger: public std::enable_shared_from_this // bool HasCacheValue(int valueIndex) const; void ClearCache() const; + int GetTypeFromName(const char* typeName); + lua_State* currentL; lua_State* mainL; @@ -137,4 +142,6 @@ class Debugger: public std::enable_shared_from_this std::queue> evalQueue; Arena *arenaRef; + + std::bitset registeredTypes; }; diff --git a/emmy_debugger/include/emmy_debugger/debugger/emmy_debugger_lib.h b/emmy_debugger/include/emmy_debugger/debugger/emmy_debugger_lib.h index f79fcfc..52d0dfe 100644 --- a/emmy_debugger/include/emmy_debugger/debugger/emmy_debugger_lib.h +++ b/emmy_debugger/include/emmy_debugger/debugger/emmy_debugger_lib.h @@ -28,6 +28,9 @@ int tcpSharedListen(lua_State* L); // emmy.stop() int stop(lua_State* L); +// emmy.registerTypeName(typeName: string): bool +int registerTypeName(lua_State* L); + bool install_emmy_debugger(struct lua_State* L); std::string prepareEvalExpr(const std::string& eval); diff --git a/emmy_debugger/include/emmy_debugger/debugger/extension_point.h b/emmy_debugger/include/emmy_debugger/debugger/extension_point.h index f4658b4..59bf573 100644 --- a/emmy_debugger/include/emmy_debugger/debugger/extension_point.h +++ b/emmy_debugger/include/emmy_debugger/debugger/extension_point.h @@ -13,6 +13,10 @@ class ExtensionPoint { void Initialize(lua_State *L); // bool QueryVariable(lua_State *L, Idx variable, const char *typeName, int object, int depth); + bool QueryVariableCustom(lua_State *L, Idx variable, const char *typeName, int object, int depth); lua_State *QueryParentThread(lua_State *L); + +private: + bool QueryVariableGeneric(lua_State *L, Idx variable, const char *typeName, int object, int depth, const char* queryFunction); }; diff --git a/emmy_debugger/include/emmy_debugger/emmy_facade.h b/emmy_debugger/include/emmy_debugger/emmy_facade.h index 551bc18..75ee590 100644 --- a/emmy_debugger/include/emmy_debugger/emmy_facade.h +++ b/emmy_debugger/include/emmy_debugger/emmy_facade.h @@ -58,6 +58,7 @@ class EmmyFacade bool PipeListen(lua_State* L, const std::string& name, std::string& err); bool PipeConnect(lua_State* L, const std::string& name, std::string& err); int BreakHere(lua_State* L); + bool RegisterTypeName(lua_State *L, const std::string &typeName, std::string &err); int OnConnect(bool suc); int OnDisconnect(); diff --git a/emmy_debugger/src/debugger/emmy_debugger.cpp b/emmy_debugger/src/debugger/emmy_debugger.cpp index ad49e0b..fe5bf8b 100644 --- a/emmy_debugger/src/debugger/emmy_debugger.cpp +++ b/emmy_debugger/src/debugger/emmy_debugger.cpp @@ -370,9 +370,13 @@ void Debugger::GetVariable(lua_State *L, Idx variable, int index, int variable->valueTypeName = typeName; variable->valueType = type; - - if (queryHelper && (type == LUA_TTABLE || type == LUA_TUSERDATA || type == LUA_TFUNCTION)) { - if (manager->extension.QueryVariable(L, variable, typeName, index, depth)) { + if (queryHelper) { + if (type >= 0 && type < registeredTypes.size() && registeredTypes.test(type) + && manager->extension.QueryVariableCustom(L, variable, typeName, index, depth)) { + return; + } + else if ((type == LUA_TTABLE || type == LUA_TUSERDATA || type == LUA_TFUNCTION) + && manager->extension.QueryVariable(L, variable, typeName, index, depth)) { return; } } @@ -1424,3 +1428,26 @@ void Debugger::ExecuteOnLuaThread(const Executor &exec) { std::unique_lock lock(luaThreadMtx); luaThreadExecutors.push_back(exec); } + +int Debugger::GetTypeFromName(const char* typeName) { + if (strcmp(typeName, "nil") == 0) return LUA_TNIL; + if (strcmp(typeName, "boolean") == 0) return LUA_TBOOLEAN; + if (strcmp(typeName, "lightuserdata") == 0) return LUA_TLIGHTUSERDATA; + if (strcmp(typeName, "number") == 0) return LUA_TNUMBER; + if (strcmp(typeName, "string") == 0) return LUA_TSTRING; + if (strcmp(typeName, "table") == 0) return LUA_TTABLE; + if (strcmp(typeName, "function") == 0) return LUA_TFUNCTION; + if (strcmp(typeName, "userdata") == 0) return LUA_TUSERDATA; + if (strcmp(typeName, "thread") == 0) return LUA_TTHREAD; + return -1; // 未知类型 +} + +bool Debugger::RegisterTypeName(const std::string& typeName, std::string& err) { + int type = GetTypeFromName(typeName.c_str()); + if (type == -1) { + err = "Unknown type name: " + typeName; + return false; + } + registeredTypes.set(type); + return true; +} \ No newline at end of file diff --git a/emmy_debugger/src/debugger/emmy_debugger_lib.cpp b/emmy_debugger/src/debugger/emmy_debugger_lib.cpp index 292ccda..d9ea800 100644 --- a/emmy_debugger/src/debugger/emmy_debugger_lib.cpp +++ b/emmy_debugger/src/debugger/emmy_debugger_lib.cpp @@ -117,6 +117,19 @@ int stop(lua_State* L) return 0; } +// emmy.registerTypeName(typeName: string): bool +int registerTypeName(lua_State* L) +{ + luaL_checkstring(L, 1); + std::string err; + const auto typeName = lua_tostring(L, 1); + const auto suc = EmmyFacade::Get().RegisterTypeName(L, typeName, err); + lua_pushboolean(L, suc); + if (suc) return 1; + lua_pushstring(L, err.c_str()); + return 2; +} + int gc(lua_State* L) { EmmyFacade::Get().OnLuaStateGC(L); diff --git a/emmy_debugger/src/debugger/extension_point.cpp b/emmy_debugger/src/debugger/extension_point.cpp index a94d2ed..e048384 100644 --- a/emmy_debugger/src/debugger/extension_point.cpp +++ b/emmy_debugger/src/debugger/extension_point.cpp @@ -122,14 +122,14 @@ void ExtensionPoint::Initialize(lua_State *L) { lua_rawset(L, LUA_REGISTRYINDEX); } -bool ExtensionPoint::QueryVariable(lua_State *L, Idx variable, const char *typeName, int object, int depth) { +bool ExtensionPoint::QueryVariableGeneric(lua_State *L, Idx variable, const char *typeName, int object, int depth, const char* queryFunction) { bool result = false; object = lua_absindex(L, object); const int t = lua_gettop(L); lua_getglobal(L, ExtensionTable.c_str()); if (lua_istable(L, -1)) { - lua_getfield(L, -1, "queryVariable"); + lua_getfield(L, -1, queryFunction); if (lua_isfunction(L, -1)) { pushVariable(L, variable); lua_pushvalue(L, object); @@ -140,7 +140,7 @@ bool ExtensionPoint::QueryVariable(lua_State *L, Idx variable, const c result = lua_toboolean(L, -1); } else { const auto err = lua_tostring(L, -1); - printf("query error: %s\n", err); + printf("query error in %s: %s\n", queryFunction, err); } } } @@ -149,6 +149,14 @@ bool ExtensionPoint::QueryVariable(lua_State *L, Idx variable, const c return result; } +bool ExtensionPoint::QueryVariable(lua_State *L, Idx variable, const char *typeName, int object, int depth) { + return QueryVariableGeneric(L, variable, typeName, object, depth, "queryVariable"); +} + +bool ExtensionPoint::QueryVariableCustom(lua_State *L, Idx variable, const char *typeName, int object, int depth) { + return QueryVariableGeneric(L, variable, typeName, object, depth, "queryVariableCustom"); +} + lua_State *ExtensionPoint::QueryParentThread(lua_State *L) { lua_State *PL = nullptr; const int t = lua_gettop(L); diff --git a/emmy_debugger/src/emmy_facade.cpp b/emmy_debugger/src/emmy_facade.cpp index 82d070f..ff331d4 100644 --- a/emmy_debugger/src/emmy_facade.cpp +++ b/emmy_debugger/src/emmy_facade.cpp @@ -396,3 +396,13 @@ void EmmyFacade::Attach(lua_State *L) { lua_sethook(L, EmmyFacade::HookLua, LUA_MASKCALL | LUA_MASKLINE | LUA_MASKRET, 0); } + +bool EmmyFacade::RegisterTypeName(lua_State *L, const std::string &typeName, std::string &err) { + auto debugger = GetDebugger(L); + if (!debugger) { + err = "Debugger does not exist"; + return false; + } + const auto suc = debugger->RegisterTypeName(typeName, err); + return suc; +}