tammela updated this revision to Diff 312942.
tammela added a comment.
Addressing comments
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D93481/new/
https://reviews.llvm.org/D93481
Files:
lldb/source/Plugins/ScriptInterpreter/Lua/Lua.cpp
lldb/source/Plugins/ScriptInterpreter/Lua/Lua.h
lldb/source/Plugins/ScriptInterpreter/Lua/ScriptInterpreterLua.cpp
lldb/source/Plugins/ScriptInterpreter/Lua/ScriptInterpreterLua.h
lldb/test/Shell/ScriptInterpreter/Lua/breakpoint_callback.test
lldb/test/Shell/ScriptInterpreter/Lua/partial_statements.test
Index: lldb/test/Shell/ScriptInterpreter/Lua/partial_statements.test
===================================================================
--- /dev/null
+++ lldb/test/Shell/ScriptInterpreter/Lua/partial_statements.test
@@ -0,0 +1,15 @@
+# REQUIRES: lua
+# RUN: %lldb -s %s --script-language lua 2>&1 | FileCheck %s
+script
+do
+local a = 123
+print(a)
+end
+# CHECK: 123
+str = 'hello there!'
+function callme()
+print(str)
+end
+callme()
+# CHECK: hello there!
+# CHECK-NOT: error
Index: lldb/test/Shell/ScriptInterpreter/Lua/breakpoint_callback.test
===================================================================
--- lldb/test/Shell/ScriptInterpreter/Lua/breakpoint_callback.test
+++ lldb/test/Shell/ScriptInterpreter/Lua/breakpoint_callback.test
@@ -1,5 +1,13 @@
# REQUIRES: lua
-# RUN: %lldb -s %s --script-language lua 2>&1 | FileCheck %s
+# RUN: echo "int main() { return 0; }" | %clang_host -x c - -o %t
+# RUN: %lldb -s %s --script-language lua %t 2>&1 | FileCheck %s
b main
breakpoint command add -s lua
-# CHECK: error: This script interpreter does not support breakpoint callbacks
+local a = 123
+print(a)
+quit
+run
+# CHECK: 123
+breakpoint command add -s lua
+789_nil
+# CHECK: unexpected symbol near '789'
Index: lldb/source/Plugins/ScriptInterpreter/Lua/ScriptInterpreterLua.h
===================================================================
--- lldb/source/Plugins/ScriptInterpreter/Lua/ScriptInterpreterLua.h
+++ lldb/source/Plugins/ScriptInterpreter/Lua/ScriptInterpreterLua.h
@@ -65,6 +65,10 @@
llvm::Error EnterSession(lldb::user_id_t debugger_id);
llvm::Error LeaveSession();
+ void CollectDataForBreakpointCommandCallback(
+ std::vector<BreakpointOptions *> &bp_options_vec,
+ CommandReturnObject &result) override;
+
Status SetBreakpointCommandCallback(BreakpointOptions *bp_options,
const char *command_body_text) override;
Index: lldb/source/Plugins/ScriptInterpreter/Lua/ScriptInterpreterLua.cpp
===================================================================
--- lldb/source/Plugins/ScriptInterpreter/Lua/ScriptInterpreterLua.cpp
+++ lldb/source/Plugins/ScriptInterpreter/Lua/ScriptInterpreterLua.cpp
@@ -17,23 +17,33 @@
#include "lldb/Utility/Stream.h"
#include "lldb/Utility/StringList.h"
#include "lldb/Utility/Timer.h"
+#include "llvm/ADT/StringRef.h"
#include "llvm/Support/FormatAdapters.h"
#include <memory>
+#include <vector>
using namespace lldb;
using namespace lldb_private;
LLDB_PLUGIN_DEFINE(ScriptInterpreterLua)
+enum ActiveIOHandler {
+ eIOHandlerNone,
+ eIOHandlerBreakpoint,
+ eIOHandlerWatchpoint
+};
+
class IOHandlerLuaInterpreter : public IOHandlerDelegate,
public IOHandlerEditline {
public:
IOHandlerLuaInterpreter(Debugger &debugger,
- ScriptInterpreterLua &script_interpreter)
+ ScriptInterpreterLua &script_interpreter,
+ ActiveIOHandler active_io_handler = eIOHandlerNone)
: IOHandlerEditline(debugger, IOHandler::Type::LuaInterpreter, "lua",
">>> ", "..> ", true, debugger.GetUseColor(), 0,
*this, nullptr),
- m_script_interpreter(script_interpreter) {
+ m_script_interpreter(script_interpreter),
+ m_active_io_handler(active_io_handler) {
llvm::cantFail(m_script_interpreter.GetLua().ChangeIO(
debugger.GetOutputFile().GetStream(),
debugger.GetErrorFile().GetStream()));
@@ -44,20 +54,79 @@
llvm::cantFail(m_script_interpreter.LeaveSession());
}
- void IOHandlerInputComplete(IOHandler &io_handler,
- std::string &data) override {
- if (llvm::StringRef(data).rtrim() == "quit") {
- io_handler.SetIsDone(true);
+ void IOHandlerActivated(IOHandler &io_handler, bool interactive) override {
+ const char *instructions = nullptr;
+ switch (m_active_io_handler) {
+ case eIOHandlerNone:
+ case eIOHandlerWatchpoint:
+ break;
+ case eIOHandlerBreakpoint:
+ instructions = "Enter your Lua command(s). Type 'quit' to end.\n"
+ "The commands are compiled as the body of the following "
+ "Lua function\n"
+ "function (frame, bp_loc, ...) end\n";
+ SetPrompt(llvm::StringRef("..> "));
+ break;
+ }
+ if (instructions == nullptr)
return;
+ if (interactive)
+ *io_handler.GetOutputStreamFileSP() << instructions;
+ }
+
+ bool IOHandlerIsInputComplete(IOHandler &io_handler,
+ StringList &lines) override {
+ size_t last = lines.GetSize() - 1;
+ if (IsQuitCommand(lines.GetStringAtIndex(last))) {
+ if (m_active_io_handler == eIOHandlerBreakpoint)
+ lines.DeleteStringAtIndex(last);
+ return true;
+ }
+ StreamString str;
+ lines.Join("\n", str);
+ if (llvm::Error E =
+ m_script_interpreter.GetLua().LoadBuffer(str.GetString())) {
+ std::string error_str = toString(std::move(E));
+ // Lua always errors out to incomplete code with '<eof>'
+ return error_str.find("<eof>") == std::string::npos;
}
+ // The breakpoint handler only exits with a explicit 'quit'
+ return m_active_io_handler != eIOHandlerBreakpoint;
+ }
- if (llvm::Error error = m_script_interpreter.GetLua().Run(data)) {
- *GetOutputStreamFileSP() << llvm::toString(std::move(error));
+ void IOHandlerInputComplete(IOHandler &io_handler,
+ std::string &data) override {
+ switch (m_active_io_handler) {
+ case eIOHandlerBreakpoint: {
+ auto *bp_options_vec = static_cast<std::vector<BreakpointOptions *> *>(
+ io_handler.GetUserData());
+ for (auto *bp_options : *bp_options_vec) {
+ Status error = m_script_interpreter.SetBreakpointCommandCallback(
+ bp_options, data.c_str());
+ if (error.Fail())
+ *io_handler.GetErrorStreamFileSP() << error.AsCString() << '\n';
+ }
+ io_handler.SetIsDone(true);
+ } break;
+ case eIOHandlerWatchpoint:
+ io_handler.SetIsDone(true);
+ break;
+ case eIOHandlerNone:
+ if (IsQuitCommand(data)) {
+ io_handler.SetIsDone(true);
+ return;
+ }
+ if (llvm::Error error = m_script_interpreter.GetLua().Run(data))
+ *io_handler.GetErrorStreamFileSP() << toString(std::move(error));
+ break;
}
}
private:
ScriptInterpreterLua &m_script_interpreter;
+ ActiveIOHandler m_active_io_handler;
+
+ bool IsQuitCommand(llvm::StringRef cmd) { return cmd.rtrim() == "quit"; }
};
ScriptInterpreterLua::ScriptInterpreterLua(Debugger &debugger)
@@ -206,6 +275,15 @@
return *BoolOrErr;
}
+void ScriptInterpreterLua::CollectDataForBreakpointCommandCallback(
+ std::vector<BreakpointOptions *> &bp_options_vec,
+ CommandReturnObject &result) {
+ IOHandlerSP io_handler_sp(
+ new IOHandlerLuaInterpreter(m_debugger, *this, eIOHandlerBreakpoint));
+ io_handler_sp->SetUserData(&bp_options_vec);
+ m_debugger.RunIOHandlerAsync(io_handler_sp);
+}
+
Status ScriptInterpreterLua::SetBreakpointCommandCallback(
BreakpointOptions *bp_options, const char *command_body_text) {
Status error;
Index: lldb/source/Plugins/ScriptInterpreter/Lua/Lua.h
===================================================================
--- lldb/source/Plugins/ScriptInterpreter/Lua/Lua.h
+++ lldb/source/Plugins/ScriptInterpreter/Lua/Lua.h
@@ -36,6 +36,7 @@
CallBreakpointCallback(void *baton, lldb::StackFrameSP stop_frame_sp,
lldb::BreakpointLocationSP bp_loc_sp);
llvm::Error LoadModule(llvm::StringRef filename);
+ llvm::Error LoadBuffer(llvm::StringRef buffer, bool pop_result = true);
llvm::Error ChangeIO(FILE *out, FILE *err);
private:
Index: lldb/source/Plugins/ScriptInterpreter/Lua/Lua.cpp
===================================================================
--- lldb/source/Plugins/ScriptInterpreter/Lua/Lua.cpp
+++ lldb/source/Plugins/ScriptInterpreter/Lua/Lua.cpp
@@ -66,9 +66,10 @@
}
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 (llvm::Error e = LoadBuffer(buffer, false))
+ return e;
+
+ int error = lua_pcall(m_lua_state, 0, 0, 0);
if (error == LUA_OK)
return llvm::Error::success();
@@ -105,6 +106,22 @@
bp_loc_sp);
}
+llvm::Error Lua::LoadBuffer(llvm::StringRef buffer, bool pop_result) {
+ int error =
+ luaL_loadbuffer(m_lua_state, buffer.data(), buffer.size(), "buffer");
+ if (error == LUA_OK) {
+ lua_pop(m_lua_state, pop_result ? 1 : 0);
+ 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)) {
_______________________________________________
lldb-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits