xref: /llvm-project/lldb/source/Plugins/ScriptInterpreter/Lua/ScriptInterpreterLua.cpp (revision 4164be7206d740b77b5a7b4b2f859ed122d08c10)
1 //===-- ScriptInterpreterLua.cpp --------------------------------*- C++ -*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
9 #include "ScriptInterpreterLua.h"
10 #include "Lua.h"
11 #include "lldb/Core/Debugger.h"
12 #include "lldb/Core/PluginManager.h"
13 #include "lldb/Core/StreamFile.h"
14 #include "lldb/Interpreter/CommandReturnObject.h"
15 #include "lldb/Utility/Stream.h"
16 #include "lldb/Utility/StringList.h"
17 #include "lldb/Utility/Timer.h"
18 
19 using namespace lldb;
20 using namespace lldb_private;
21 
22 class IOHandlerLuaInterpreter : public IOHandlerDelegate,
23                                 public IOHandlerEditline {
24 public:
25   IOHandlerLuaInterpreter(Debugger &debugger,
26                           ScriptInterpreterLua &script_interpreter)
27       : IOHandlerEditline(debugger, IOHandler::Type::LuaInterpreter, "lua",
28                           ">>> ", "..> ", true, debugger.GetUseColor(), 0,
29                           *this, nullptr),
30         m_script_interpreter(script_interpreter) {}
31 
32   void IOHandlerInputComplete(IOHandler &io_handler,
33                               std::string &data) override {
34     if (llvm::Error error = m_script_interpreter.GetLua().Run(data)) {
35       *GetOutputStreamFileSP() << llvm::toString(std::move(error));
36     }
37   }
38 
39 private:
40   ScriptInterpreterLua &m_script_interpreter;
41 };
42 
43 ScriptInterpreterLua::ScriptInterpreterLua(Debugger &debugger)
44     : ScriptInterpreter(debugger, eScriptLanguageLua),
45       m_lua(std::make_unique<Lua>()) {}
46 
47 ScriptInterpreterLua::~ScriptInterpreterLua() {}
48 
49 bool ScriptInterpreterLua::ExecuteOneLine(llvm::StringRef command,
50                                           CommandReturnObject *result,
51                                           const ExecuteScriptOptions &options) {
52   if (llvm::Error e = m_lua->Run(command)) {
53     result->AppendErrorWithFormatv(
54         "lua failed attempting to evaluate '{0}': {1}\n", command,
55         llvm::toString(std::move(e)));
56     return false;
57   }
58   return true;
59 }
60 
61 void ScriptInterpreterLua::ExecuteInterpreterLoop() {
62   static Timer::Category func_cat(LLVM_PRETTY_FUNCTION);
63   Timer scoped_timer(func_cat, LLVM_PRETTY_FUNCTION);
64 
65   Debugger &debugger = m_debugger;
66 
67   // At the moment, the only time the debugger does not have an input file
68   // handle is when this is called directly from lua, in which case it is
69   // both dangerous and unnecessary (not to mention confusing) to try to embed
70   // a running interpreter loop inside the already running lua interpreter
71   // loop, so we won't do it.
72 
73   if (!debugger.GetInputFile().IsValid())
74     return;
75 
76   IOHandlerSP io_handler_sp(new IOHandlerLuaInterpreter(debugger, *this));
77   debugger.PushIOHandler(io_handler_sp);
78 }
79 
80 void ScriptInterpreterLua::Initialize() {
81   static llvm::once_flag g_once_flag;
82 
83   llvm::call_once(g_once_flag, []() {
84     PluginManager::RegisterPlugin(GetPluginNameStatic(),
85                                   GetPluginDescriptionStatic(),
86                                   lldb::eScriptLanguageLua, CreateInstance);
87   });
88 }
89 
90 void ScriptInterpreterLua::Terminate() {}
91 
92 lldb::ScriptInterpreterSP
93 ScriptInterpreterLua::CreateInstance(Debugger &debugger) {
94   return std::make_shared<ScriptInterpreterLua>(debugger);
95 }
96 
97 lldb_private::ConstString ScriptInterpreterLua::GetPluginNameStatic() {
98   static ConstString g_name("script-lua");
99   return g_name;
100 }
101 
102 const char *ScriptInterpreterLua::GetPluginDescriptionStatic() {
103   return "Lua script interpreter";
104 }
105 
106 lldb_private::ConstString ScriptInterpreterLua::GetPluginName() {
107   return GetPluginNameStatic();
108 }
109 
110 uint32_t ScriptInterpreterLua::GetPluginVersion() { return 1; }
111 
112 Lua &ScriptInterpreterLua::GetLua() { return *m_lua; }
113