xref: /freebsd-src/contrib/llvm-project/lldb/source/Plugins/ScriptInterpreter/Lua/Lua.cpp (revision 5ffd83dbcc34f10e07f6d3e968ae6365869615f4)
1480093f4SDimitry Andric //===-- Lua.cpp -----------------------------------------------------------===//
2480093f4SDimitry Andric //
3480093f4SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4480093f4SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
5480093f4SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6480093f4SDimitry Andric //
7480093f4SDimitry Andric //===----------------------------------------------------------------------===//
8480093f4SDimitry Andric 
9480093f4SDimitry Andric #include "Lua.h"
10480093f4SDimitry Andric #include "lldb/Host/FileSystem.h"
11480093f4SDimitry Andric #include "lldb/Utility/FileSpec.h"
12480093f4SDimitry Andric #include "llvm/Support/FormatVariadic.h"
13480093f4SDimitry Andric 
14480093f4SDimitry Andric using namespace lldb_private;
15480093f4SDimitry Andric using namespace lldb;
16480093f4SDimitry Andric 
17480093f4SDimitry Andric llvm::Error Lua::Run(llvm::StringRef buffer) {
18480093f4SDimitry Andric   int error =
19480093f4SDimitry Andric       luaL_loadbuffer(m_lua_state, buffer.data(), buffer.size(), "buffer") ||
20480093f4SDimitry Andric       lua_pcall(m_lua_state, 0, 0, 0);
21480093f4SDimitry Andric   if (!error)
22480093f4SDimitry Andric     return llvm::Error::success();
23480093f4SDimitry Andric 
24480093f4SDimitry Andric   llvm::Error e = llvm::make_error<llvm::StringError>(
25480093f4SDimitry Andric       llvm::formatv("{0}\n", lua_tostring(m_lua_state, -1)),
26480093f4SDimitry Andric       llvm::inconvertibleErrorCode());
27480093f4SDimitry Andric   // Pop error message from the stack.
28480093f4SDimitry Andric   lua_pop(m_lua_state, 1);
29480093f4SDimitry Andric   return e;
30480093f4SDimitry Andric }
31480093f4SDimitry Andric 
32480093f4SDimitry Andric llvm::Error Lua::LoadModule(llvm::StringRef filename) {
33480093f4SDimitry Andric   FileSpec file(filename);
34480093f4SDimitry Andric   if (!FileSystem::Instance().Exists(file)) {
35480093f4SDimitry Andric     return llvm::make_error<llvm::StringError>("invalid path",
36480093f4SDimitry Andric                                                llvm::inconvertibleErrorCode());
37480093f4SDimitry Andric   }
38480093f4SDimitry Andric 
39480093f4SDimitry Andric   ConstString module_extension = file.GetFileNameExtension();
40480093f4SDimitry Andric   if (module_extension != ".lua") {
41480093f4SDimitry Andric     return llvm::make_error<llvm::StringError>("invalid extension",
42480093f4SDimitry Andric                                                llvm::inconvertibleErrorCode());
43480093f4SDimitry Andric   }
44480093f4SDimitry Andric 
45480093f4SDimitry Andric   int error = luaL_loadfile(m_lua_state, filename.data()) ||
46480093f4SDimitry Andric               lua_pcall(m_lua_state, 0, 1, 0);
47480093f4SDimitry Andric   if (error) {
48480093f4SDimitry Andric     llvm::Error e = llvm::make_error<llvm::StringError>(
49480093f4SDimitry Andric         llvm::formatv("{0}\n", lua_tostring(m_lua_state, -1)),
50480093f4SDimitry Andric         llvm::inconvertibleErrorCode());
51480093f4SDimitry Andric     // Pop error message from the stack.
52480093f4SDimitry Andric     lua_pop(m_lua_state, 1);
53480093f4SDimitry Andric     return e;
54480093f4SDimitry Andric   }
55480093f4SDimitry Andric 
56480093f4SDimitry Andric   ConstString module_name = file.GetFileNameStrippingExtension();
57480093f4SDimitry Andric   lua_setglobal(m_lua_state, module_name.GetCString());
58480093f4SDimitry Andric   return llvm::Error::success();
59480093f4SDimitry Andric }
60*5ffd83dbSDimitry Andric 
61*5ffd83dbSDimitry Andric llvm::Error Lua::ChangeIO(FILE *out, FILE *err) {
62*5ffd83dbSDimitry Andric   assert(out != nullptr);
63*5ffd83dbSDimitry Andric   assert(err != nullptr);
64*5ffd83dbSDimitry Andric 
65*5ffd83dbSDimitry Andric   lua_getglobal(m_lua_state, "io");
66*5ffd83dbSDimitry Andric 
67*5ffd83dbSDimitry Andric   lua_getfield(m_lua_state, -1, "stdout");
68*5ffd83dbSDimitry Andric   if (luaL_Stream *s = static_cast<luaL_Stream *>(
69*5ffd83dbSDimitry Andric           luaL_testudata(m_lua_state, -1, LUA_FILEHANDLE))) {
70*5ffd83dbSDimitry Andric     s->f = out;
71*5ffd83dbSDimitry Andric     lua_pop(m_lua_state, 1);
72*5ffd83dbSDimitry Andric   } else {
73*5ffd83dbSDimitry Andric     lua_pop(m_lua_state, 2);
74*5ffd83dbSDimitry Andric     return llvm::make_error<llvm::StringError>("could not get stdout",
75*5ffd83dbSDimitry Andric                                                llvm::inconvertibleErrorCode());
76*5ffd83dbSDimitry Andric   }
77*5ffd83dbSDimitry Andric 
78*5ffd83dbSDimitry Andric   lua_getfield(m_lua_state, -1, "stderr");
79*5ffd83dbSDimitry Andric   if (luaL_Stream *s = static_cast<luaL_Stream *>(
80*5ffd83dbSDimitry Andric           luaL_testudata(m_lua_state, -1, LUA_FILEHANDLE))) {
81*5ffd83dbSDimitry Andric     s->f = out;
82*5ffd83dbSDimitry Andric     lua_pop(m_lua_state, 1);
83*5ffd83dbSDimitry Andric   } else {
84*5ffd83dbSDimitry Andric     lua_pop(m_lua_state, 2);
85*5ffd83dbSDimitry Andric     return llvm::make_error<llvm::StringError>("could not get stderr",
86*5ffd83dbSDimitry Andric                                                llvm::inconvertibleErrorCode());
87*5ffd83dbSDimitry Andric   }
88*5ffd83dbSDimitry Andric 
89*5ffd83dbSDimitry Andric   lua_pop(m_lua_state, 1);
90*5ffd83dbSDimitry Andric   return llvm::Error::success();
91*5ffd83dbSDimitry Andric }
92