128613242SJonas Devlieghere //===-- Lua.cpp -----------------------------------------------------------===// 228613242SJonas Devlieghere // 328613242SJonas Devlieghere // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 428613242SJonas Devlieghere // See https://llvm.org/LICENSE.txt for license information. 528613242SJonas Devlieghere // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 628613242SJonas Devlieghere // 728613242SJonas Devlieghere //===----------------------------------------------------------------------===// 828613242SJonas Devlieghere 928613242SJonas Devlieghere #include "Lua.h" 10572b9f46SJonas Devlieghere #include "lldb/Host/FileSystem.h" 11572b9f46SJonas Devlieghere #include "lldb/Utility/FileSpec.h" 1228613242SJonas Devlieghere #include "llvm/Support/FormatVariadic.h" 1328613242SJonas Devlieghere 1428613242SJonas Devlieghere using namespace lldb_private; 1545c971f7SJonas Devlieghere using namespace lldb; 1628613242SJonas Devlieghere 1728613242SJonas Devlieghere llvm::Error Lua::Run(llvm::StringRef buffer) { 1828613242SJonas Devlieghere int error = 1928613242SJonas Devlieghere luaL_loadbuffer(m_lua_state, buffer.data(), buffer.size(), "buffer") || 2028613242SJonas Devlieghere lua_pcall(m_lua_state, 0, 0, 0); 2128613242SJonas Devlieghere if (!error) 2228613242SJonas Devlieghere return llvm::Error::success(); 2328613242SJonas Devlieghere 2428613242SJonas Devlieghere llvm::Error e = llvm::make_error<llvm::StringError>( 2528613242SJonas Devlieghere llvm::formatv("{0}\n", lua_tostring(m_lua_state, -1)), 2628613242SJonas Devlieghere llvm::inconvertibleErrorCode()); 2728613242SJonas Devlieghere // Pop error message from the stack. 2828613242SJonas Devlieghere lua_pop(m_lua_state, 1); 2928613242SJonas Devlieghere return e; 3028613242SJonas Devlieghere } 31572b9f46SJonas Devlieghere 32572b9f46SJonas Devlieghere llvm::Error Lua::LoadModule(llvm::StringRef filename) { 33572b9f46SJonas Devlieghere FileSpec file(filename); 34572b9f46SJonas Devlieghere if (!FileSystem::Instance().Exists(file)) { 35572b9f46SJonas Devlieghere return llvm::make_error<llvm::StringError>("invalid path", 36572b9f46SJonas Devlieghere llvm::inconvertibleErrorCode()); 37572b9f46SJonas Devlieghere } 38572b9f46SJonas Devlieghere 39572b9f46SJonas Devlieghere ConstString module_extension = file.GetFileNameExtension(); 40572b9f46SJonas Devlieghere if (module_extension != ".lua") { 41572b9f46SJonas Devlieghere return llvm::make_error<llvm::StringError>("invalid extension", 42572b9f46SJonas Devlieghere llvm::inconvertibleErrorCode()); 43572b9f46SJonas Devlieghere } 44572b9f46SJonas Devlieghere 45572b9f46SJonas Devlieghere int error = luaL_loadfile(m_lua_state, filename.data()) || 46572b9f46SJonas Devlieghere lua_pcall(m_lua_state, 0, 1, 0); 47572b9f46SJonas Devlieghere if (error) { 48572b9f46SJonas Devlieghere llvm::Error e = llvm::make_error<llvm::StringError>( 49572b9f46SJonas Devlieghere llvm::formatv("{0}\n", lua_tostring(m_lua_state, -1)), 50572b9f46SJonas Devlieghere llvm::inconvertibleErrorCode()); 51572b9f46SJonas Devlieghere // Pop error message from the stack. 52572b9f46SJonas Devlieghere lua_pop(m_lua_state, 1); 53572b9f46SJonas Devlieghere return e; 54572b9f46SJonas Devlieghere } 55572b9f46SJonas Devlieghere 56572b9f46SJonas Devlieghere ConstString module_name = file.GetFileNameStrippingExtension(); 57572b9f46SJonas Devlieghere lua_setglobal(m_lua_state, module_name.GetCString()); 58572b9f46SJonas Devlieghere return llvm::Error::success(); 59572b9f46SJonas Devlieghere } 60fa1b4a96SJonas Devlieghere 61fa1b4a96SJonas Devlieghere llvm::Error Lua::ChangeIO(FILE *out, FILE *err) { 62fa1b4a96SJonas Devlieghere assert(out != nullptr); 63fa1b4a96SJonas Devlieghere assert(err != nullptr); 64fa1b4a96SJonas Devlieghere 65fa1b4a96SJonas Devlieghere lua_getglobal(m_lua_state, "io"); 66fa1b4a96SJonas Devlieghere 67fa1b4a96SJonas Devlieghere lua_getfield(m_lua_state, -1, "stdout"); 68fa1b4a96SJonas Devlieghere if (luaL_Stream *s = static_cast<luaL_Stream *>( 69fa1b4a96SJonas Devlieghere luaL_testudata(m_lua_state, -1, LUA_FILEHANDLE))) { 70fa1b4a96SJonas Devlieghere s->f = out; 71fa1b4a96SJonas Devlieghere lua_pop(m_lua_state, 1); 72fa1b4a96SJonas Devlieghere } else { 73fa1b4a96SJonas Devlieghere lua_pop(m_lua_state, 2); 74fa1b4a96SJonas Devlieghere return llvm::make_error<llvm::StringError>("could not get stdout", 75fa1b4a96SJonas Devlieghere llvm::inconvertibleErrorCode()); 76fa1b4a96SJonas Devlieghere } 77fa1b4a96SJonas Devlieghere 78*be494adbSJonas Devlieghere lua_getfield(m_lua_state, -1, "stderr"); 79fa1b4a96SJonas Devlieghere if (luaL_Stream *s = static_cast<luaL_Stream *>( 80fa1b4a96SJonas Devlieghere luaL_testudata(m_lua_state, -1, LUA_FILEHANDLE))) { 81fa1b4a96SJonas Devlieghere s->f = out; 82fa1b4a96SJonas Devlieghere lua_pop(m_lua_state, 1); 83fa1b4a96SJonas Devlieghere } else { 84fa1b4a96SJonas Devlieghere lua_pop(m_lua_state, 2); 85fa1b4a96SJonas Devlieghere return llvm::make_error<llvm::StringError>("could not get stderr", 86fa1b4a96SJonas Devlieghere llvm::inconvertibleErrorCode()); 87fa1b4a96SJonas Devlieghere } 88fa1b4a96SJonas Devlieghere 89fa1b4a96SJonas Devlieghere lua_pop(m_lua_state, 1); 90fa1b4a96SJonas Devlieghere return llvm::Error::success(); 91fa1b4a96SJonas Devlieghere } 92