summaryrefslogtreecommitdiffstats
path: root/lldb/source
diff options
context:
space:
mode:
authorJonas Devlieghere <jonas@devlieghere.com>2019-12-07 17:35:31 -0800
committerJonas Devlieghere <jonas@devlieghere.com>2019-12-20 11:19:47 -0800
commit2861324208e13846eb306f01b32448f94177cc3b (patch)
treeb47908336cb73f749fb4799dc5e877817ded4f0b /lldb/source
parent2a42a5a2f4144cd99812ad0d230480f94a1d1c92 (diff)
downloadbcm5719-llvm-2861324208e13846eb306f01b32448f94177cc3b.tar.gz
bcm5719-llvm-2861324208e13846eb306f01b32448f94177cc3b.zip
[lldb/Lua] Implement a Simple Lua Script Interpreter Prototype
This implements a very elementary Lua script interpreter. It supports running a single command as well as running interactively. It uses editline if available. It's still missing a bunch of stuff though. Some things that I intentionally ingored for now are that I/O isn't properly hooked up (so every print goes to stdout) and the non-editline support which is not handling a bunch of corner cases. The latter is a matter of reusing existing code in the Python interpreter. Discussion on the mailing list: http://lists.llvm.org/pipermail/lldb-dev/2019-December/015812.html Differential revision: https://reviews.llvm.org/D71234
Diffstat (limited to 'lldb/source')
-rw-r--r--lldb/source/Plugins/ScriptInterpreter/Lua/CMakeLists.txt6
-rw-r--r--lldb/source/Plugins/ScriptInterpreter/Lua/Lua.cpp27
-rw-r--r--lldb/source/Plugins/ScriptInterpreter/Lua/Lua.h39
-rw-r--r--lldb/source/Plugins/ScriptInterpreter/Lua/ScriptInterpreterLua.cpp60
4 files changed, 120 insertions, 12 deletions
diff --git a/lldb/source/Plugins/ScriptInterpreter/Lua/CMakeLists.txt b/lldb/source/Plugins/ScriptInterpreter/Lua/CMakeLists.txt
index 51161638a3d..498bd978395 100644
--- a/lldb/source/Plugins/ScriptInterpreter/Lua/CMakeLists.txt
+++ b/lldb/source/Plugins/ScriptInterpreter/Lua/CMakeLists.txt
@@ -1,7 +1,11 @@
add_lldb_library(lldbPluginScriptInterpreterLua PLUGIN
+ Lua.cpp
ScriptInterpreterLua.cpp
LINK_LIBS
lldbCore
lldbInterpreter
- ) \ No newline at end of file
+ )
+
+target_include_directories(lldbPluginScriptInterpreterLua PUBLIC ${LUA_INCLUDE_DIR})
+target_link_libraries(lldbPluginScriptInterpreterLua INTERFACE ${LUA_LIBRARIES})
diff --git a/lldb/source/Plugins/ScriptInterpreter/Lua/Lua.cpp b/lldb/source/Plugins/ScriptInterpreter/Lua/Lua.cpp
new file mode 100644
index 00000000000..a908ef08673
--- /dev/null
+++ b/lldb/source/Plugins/ScriptInterpreter/Lua/Lua.cpp
@@ -0,0 +1,27 @@
+//===-- Lua.cpp -----------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "Lua.h"
+#include "llvm/Support/FormatVariadic.h"
+
+using namespace lldb_private;
+
+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)
+ 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;
+}
diff --git a/lldb/source/Plugins/ScriptInterpreter/Lua/Lua.h b/lldb/source/Plugins/ScriptInterpreter/Lua/Lua.h
new file mode 100644
index 00000000000..50b7ade4dc4
--- /dev/null
+++ b/lldb/source/Plugins/ScriptInterpreter/Lua/Lua.h
@@ -0,0 +1,39 @@
+//===-- ScriptInterpreterLua.h ----------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_Lua_h_
+#define liblldb_Lua_h_
+
+#include "llvm/ADT/StringRef.h"
+#include "llvm/Support/Error.h"
+
+#include "lua.hpp"
+
+namespace lldb_private {
+
+class Lua {
+public:
+ Lua() : m_lua_state(luaL_newstate()) {
+ assert(m_lua_state);
+ luaL_openlibs(m_lua_state);
+ }
+
+ ~Lua() {
+ assert(m_lua_state);
+ luaL_openlibs(m_lua_state);
+ }
+
+ llvm::Error Run(llvm::StringRef buffer);
+
+private:
+ lua_State *m_lua_state;
+};
+
+} // namespace lldb_private
+
+#endif // liblldb_Lua_h_
diff --git a/lldb/source/Plugins/ScriptInterpreter/Lua/ScriptInterpreterLua.cpp b/lldb/source/Plugins/ScriptInterpreter/Lua/ScriptInterpreterLua.cpp
index 78aa91a6959..b3f1689909f 100644
--- a/lldb/source/Plugins/ScriptInterpreter/Lua/ScriptInterpreterLua.cpp
+++ b/lldb/source/Plugins/ScriptInterpreter/Lua/ScriptInterpreterLua.cpp
@@ -7,35 +7,73 @@
//===----------------------------------------------------------------------===//
#include "ScriptInterpreterLua.h"
+#include "Lua.h"
#include "lldb/Core/Debugger.h"
#include "lldb/Core/PluginManager.h"
#include "lldb/Core/StreamFile.h"
+#include "lldb/Interpreter/CommandReturnObject.h"
#include "lldb/Utility/Stream.h"
#include "lldb/Utility/StringList.h"
-
-#include "llvm/Support/Threading.h"
-
-#include <mutex>
+#include "lldb/Utility/Timer.h"
using namespace lldb;
using namespace lldb_private;
+class IOHandlerLuaInterpreter : public IOHandlerDelegate,
+ public IOHandlerEditline {
+public:
+ IOHandlerLuaInterpreter(Debugger &debugger)
+ : IOHandlerEditline(debugger, IOHandler::Type::LuaInterpreter, "lua",
+ ">>> ", "..> ", true, debugger.GetUseColor(), 0,
+ *this, nullptr),
+ m_lua() {}
+
+ void IOHandlerInputComplete(IOHandler &io_handler,
+ std::string &data) override {
+ if (llvm::Error error = m_lua.Run(data)) {
+ *GetOutputStreamFileSP() << llvm::toString(std::move(error));
+ }
+ }
+
+private:
+ Lua m_lua;
+};
+
ScriptInterpreterLua::ScriptInterpreterLua(Debugger &debugger)
: ScriptInterpreter(debugger, eScriptLanguageLua) {}
ScriptInterpreterLua::~ScriptInterpreterLua() {}
bool ScriptInterpreterLua::ExecuteOneLine(llvm::StringRef command,
- CommandReturnObject *,
- const ExecuteScriptOptions &) {
- m_debugger.GetErrorStream().PutCString(
- "error: the lua script interpreter is not yet implemented.\n");
- return false;
+ CommandReturnObject *result,
+ const ExecuteScriptOptions &options) {
+ Lua l;
+ if (llvm::Error e = l.Run(command)) {
+ result->AppendErrorWithFormatv(
+ "lua failed attempting to evaluate '{0}': {1}\n", command,
+ llvm::toString(std::move(e)));
+ return false;
+ }
+ return true;
}
void ScriptInterpreterLua::ExecuteInterpreterLoop() {
- m_debugger.GetErrorStream().PutCString(
- "error: the lua script interpreter is not yet implemented.\n");
+ static Timer::Category func_cat(LLVM_PRETTY_FUNCTION);
+ Timer scoped_timer(func_cat, LLVM_PRETTY_FUNCTION);
+
+ Debugger &debugger = m_debugger;
+
+ // At the moment, the only time the debugger does not have an input file
+ // handle is when this is called directly from lua, in which case it is
+ // both dangerous and unnecessary (not to mention confusing) to try to embed
+ // a running interpreter loop inside the already running lua interpreter
+ // loop, so we won't do it.
+
+ if (!debugger.GetInputFile().IsValid())
+ return;
+
+ IOHandlerSP io_handler_sp(new IOHandlerLuaInterpreter(debugger));
+ debugger.PushIOHandler(io_handler_sp);
}
void ScriptInterpreterLua::Initialize() {
OpenPOWER on IntegriCloud