[lldb/Lua] Support loading Lua modules

Implements the command script import command for Lua.

Differential revision: https://reviews.llvm.org/D71825
This commit is contained in:
Jonas Devlieghere 2020-01-10 10:21:15 -08:00
parent ef23997261
commit 572b9f468a
6 changed files with 69 additions and 0 deletions

View File

@ -7,6 +7,8 @@
//===----------------------------------------------------------------------===//
#include "Lua.h"
#include "lldb/Host/FileSystem.h"
#include "lldb/Utility/FileSpec.h"
#include "llvm/Support/FormatVariadic.h"
using namespace lldb_private;
@ -26,3 +28,32 @@ llvm::Error Lua::Run(llvm::StringRef buffer) {
lua_pop(m_lua_state, 1);
return e;
}
llvm::Error Lua::LoadModule(llvm::StringRef filename) {
FileSpec file(filename);
if (!FileSystem::Instance().Exists(file)) {
return llvm::make_error<llvm::StringError>("invalid path",
llvm::inconvertibleErrorCode());
}
ConstString module_extension = file.GetFileNameExtension();
if (module_extension != ".lua") {
return llvm::make_error<llvm::StringError>("invalid extension",
llvm::inconvertibleErrorCode());
}
int error = luaL_loadfile(m_lua_state, filename.data()) ||
lua_pcall(m_lua_state, 0, 1, 0);
if (error) {
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;
}
ConstString module_name = file.GetFileNameStrippingExtension();
lua_setglobal(m_lua_state, module_name.GetCString());
return llvm::Error::success();
}

View File

@ -37,6 +37,7 @@ public:
}
llvm::Error Run(llvm::StringRef buffer);
llvm::Error LoadModule(llvm::StringRef filename);
private:
lua_State *m_lua_state;

View File

@ -83,6 +83,18 @@ void ScriptInterpreterLua::ExecuteInterpreterLoop() {
debugger.PushIOHandler(io_handler_sp);
}
bool ScriptInterpreterLua::LoadScriptingModule(
const char *filename, bool init_session, lldb_private::Status &error,
StructuredData::ObjectSP *module_sp) {
if (llvm::Error e = m_lua->LoadModule(filename)) {
error.SetErrorStringWithFormatv("lua failed to import '{0}': {1}\n",
filename, llvm::toString(std::move(e)));
return false;
}
return true;
}
void ScriptInterpreterLua::Initialize() {
static llvm::once_flag g_once_flag;

View File

@ -25,6 +25,11 @@ public:
void ExecuteInterpreterLoop() override;
virtual bool
LoadScriptingModule(const char *filename, bool init_session,
lldb_private::Status &error,
StructuredData::ObjectSP *module_sp = nullptr) override;
// Static Functions
static void Initialize();

View File

@ -0,0 +1,7 @@
local mymodule = {}
function mymodule.foo()
print("Hello World!")
end
return mymodule

View File

@ -0,0 +1,13 @@
# REQUIRES: lua
# RUN: %lldb --script-language lua -o 'command script import %S/Inputs/testmodule.lua' -o 'script testmodule.foo()' 2>&1 | FileCheck %s
# CHECK: Hello World!
# RUN: mkdir -p %t
# RUN: cp %S/Inputs/testmodule.lua %t/testmodule.notlua
# RUN: %lldb --script-language lua -o 'command script import %t/testmodule.notlua' -o 'script testmodule.foo()' 2>&1 | FileCheck %s --check-prefix EXTENSION
# EXTENSION: error: module importing failed: lua failed to import '{{.*}}testmodule.notlua': invalid extension
# EXTENSION-NOT: Hello World!
# RUN: %lldb --script-language lua -o 'command script import %S/Inputs/bogus' -o 'script testmodule.foo()' 2>&1 | FileCheck %s --check-prefix NONEXISTING
# NONEXISTING: error: module importing failed: lua failed to import '{{.*}}bogus': invalid path
# NONEXISTING-NOT: Hello World!