diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2021-06-13 19:31:46 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2021-06-13 19:37:19 +0000 |
commit | e8d8bef961a50d4dc22501cde4fb9fb0be1b2532 (patch) | |
tree | 94f04805f47bb7c59ae29690d8952b6074fff602 /contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Lua/Lua.cpp | |
parent | bb130ff39747b94592cb26d71b7cb097b9a4ea6b (diff) | |
parent | b60736ec1405bb0a8dd40989f67ef4c93da068ab (diff) |
Diffstat (limited to 'contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Lua/Lua.cpp')
-rw-r--r-- | contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Lua/Lua.cpp | 105 |
1 files changed, 103 insertions, 2 deletions
diff --git a/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Lua/Lua.cpp b/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Lua/Lua.cpp index acd6128d84c5..f14e2732f6eb 100644 --- a/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Lua/Lua.cpp +++ b/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Lua/Lua.cpp @@ -9,16 +9,66 @@ #include "Lua.h" #include "lldb/Host/FileSystem.h" #include "lldb/Utility/FileSpec.h" +#include "llvm/Support/Error.h" #include "llvm/Support/FormatVariadic.h" using namespace lldb_private; using namespace lldb; +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wreturn-type-c-linkage" + +// Disable warning C4190: 'LLDBSwigPythonBreakpointCallbackFunction' has +// C-linkage specified, but returns UDT 'llvm::Expected<bool>' which is +// incompatible with C +#if _MSC_VER +#pragma warning (push) +#pragma warning (disable : 4190) +#endif + +extern "C" llvm::Expected<bool> LLDBSwigLuaBreakpointCallbackFunction( + lua_State *L, lldb::StackFrameSP stop_frame_sp, + lldb::BreakpointLocationSP bp_loc_sp, StructuredDataImpl *extra_args_impl); + +#if _MSC_VER +#pragma warning (pop) +#endif + +#pragma clang diagnostic pop + +static int lldb_print(lua_State *L) { + int n = lua_gettop(L); + lua_getglobal(L, "io"); + lua_getfield(L, -1, "stdout"); + lua_getfield(L, -1, "write"); + for (int i = 1; i <= n; i++) { + lua_pushvalue(L, -1); // write() + lua_pushvalue(L, -3); // io.stdout + luaL_tolstring(L, i, nullptr); + lua_pushstring(L, i != n ? "\t" : "\n"); + lua_call(L, 3, 0); + } + return 0; +} + +Lua::Lua() : m_lua_state(luaL_newstate()) { + assert(m_lua_state); + luaL_openlibs(m_lua_state); + luaopen_lldb(m_lua_state); + lua_pushcfunction(m_lua_state, lldb_print); + lua_setglobal(m_lua_state, "print"); +} + +Lua::~Lua() { + assert(m_lua_state); + lua_close(m_lua_state); +} + llvm::Error Lua::Run(llvm::StringRef buffer) { int error = luaL_loadbuffer(m_lua_state, buffer.data(), buffer.size(), "buffer") || lua_pcall(m_lua_state, 0, 0, 0); - if (!error) + if (error == LUA_OK) return llvm::Error::success(); llvm::Error e = llvm::make_error<llvm::StringError>( @@ -29,6 +79,57 @@ llvm::Error Lua::Run(llvm::StringRef buffer) { return e; } +llvm::Error Lua::RegisterBreakpointCallback(void *baton, const char *body) { + lua_pushlightuserdata(m_lua_state, baton); + const char *fmt_str = "return function(frame, bp_loc, ...) {0} end"; + std::string func_str = llvm::formatv(fmt_str, body).str(); + if (luaL_dostring(m_lua_state, func_str.c_str()) != LUA_OK) { + llvm::Error e = llvm::make_error<llvm::StringError>( + llvm::formatv("{0}", lua_tostring(m_lua_state, -1)), + llvm::inconvertibleErrorCode()); + // Pop error message from the stack. + lua_pop(m_lua_state, 2); + return e; + } + lua_settable(m_lua_state, LUA_REGISTRYINDEX); + return llvm::Error::success(); +} + +llvm::Expected<bool> +Lua::CallBreakpointCallback(void *baton, lldb::StackFrameSP stop_frame_sp, + lldb::BreakpointLocationSP bp_loc_sp, + StructuredData::ObjectSP extra_args_sp) { + + lua_pushlightuserdata(m_lua_state, baton); + lua_gettable(m_lua_state, LUA_REGISTRYINDEX); + auto *extra_args_impl = [&]() -> StructuredDataImpl * { + if (extra_args_sp == nullptr) + return nullptr; + auto *extra_args_impl = new StructuredDataImpl(); + extra_args_impl->SetObjectSP(extra_args_sp); + return extra_args_impl; + }(); + return LLDBSwigLuaBreakpointCallbackFunction(m_lua_state, stop_frame_sp, + bp_loc_sp, extra_args_impl); +} + +llvm::Error Lua::CheckSyntax(llvm::StringRef buffer) { + int error = + luaL_loadbuffer(m_lua_state, buffer.data(), buffer.size(), "buffer"); + if (error == LUA_OK) { + // Pop buffer + lua_pop(m_lua_state, 1); + return llvm::Error::success(); + } + + llvm::Error e = llvm::make_error<llvm::StringError>( + llvm::formatv("{0}\n", lua_tostring(m_lua_state, -1)), + llvm::inconvertibleErrorCode()); + // Pop error message from the stack. + lua_pop(m_lua_state, 1); + return e; +} + llvm::Error Lua::LoadModule(llvm::StringRef filename) { FileSpec file(filename); if (!FileSystem::Instance().Exists(file)) { @@ -44,7 +145,7 @@ llvm::Error Lua::LoadModule(llvm::StringRef filename) { int error = luaL_loadfile(m_lua_state, filename.data()) || lua_pcall(m_lua_state, 0, 1, 0); - if (error) { + if (error != LUA_OK) { llvm::Error e = llvm::make_error<llvm::StringError>( llvm::formatv("{0}\n", lua_tostring(m_lua_state, -1)), llvm::inconvertibleErrorCode()); |