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 } 60*fa1b4a96SJonas Devlieghere 61*fa1b4a96SJonas Devlieghere llvm::Error Lua::ChangeIO(FILE *out, FILE *err) { 62*fa1b4a96SJonas Devlieghere assert(out != nullptr); 63*fa1b4a96SJonas Devlieghere assert(err != nullptr); 64*fa1b4a96SJonas Devlieghere 65*fa1b4a96SJonas Devlieghere lua_getglobal(m_lua_state, "io"); 66*fa1b4a96SJonas Devlieghere 67*fa1b4a96SJonas Devlieghere lua_getfield(m_lua_state, -1, "stdout"); 68*fa1b4a96SJonas Devlieghere if (luaL_Stream *s = static_cast<luaL_Stream *>( 69*fa1b4a96SJonas Devlieghere luaL_testudata(m_lua_state, -1, LUA_FILEHANDLE))) { 70*fa1b4a96SJonas Devlieghere s->f = out; 71*fa1b4a96SJonas Devlieghere lua_pop(m_lua_state, 1); 72*fa1b4a96SJonas Devlieghere } else { 73*fa1b4a96SJonas Devlieghere lua_pop(m_lua_state, 2); 74*fa1b4a96SJonas Devlieghere return llvm::make_error<llvm::StringError>("could not get stdout", 75*fa1b4a96SJonas Devlieghere llvm::inconvertibleErrorCode()); 76*fa1b4a96SJonas Devlieghere } 77*fa1b4a96SJonas Devlieghere 78*fa1b4a96SJonas Devlieghere lua_getfield(m_lua_state, -1, "stdout"); 79*fa1b4a96SJonas Devlieghere if (luaL_Stream *s = static_cast<luaL_Stream *>( 80*fa1b4a96SJonas Devlieghere luaL_testudata(m_lua_state, -1, LUA_FILEHANDLE))) { 81*fa1b4a96SJonas Devlieghere s->f = out; 82*fa1b4a96SJonas Devlieghere lua_pop(m_lua_state, 1); 83*fa1b4a96SJonas Devlieghere } else { 84*fa1b4a96SJonas Devlieghere lua_pop(m_lua_state, 2); 85*fa1b4a96SJonas Devlieghere return llvm::make_error<llvm::StringError>("could not get stderr", 86*fa1b4a96SJonas Devlieghere llvm::inconvertibleErrorCode()); 87*fa1b4a96SJonas Devlieghere } 88*fa1b4a96SJonas Devlieghere 89*fa1b4a96SJonas Devlieghere lua_pop(m_lua_state, 1); 90*fa1b4a96SJonas Devlieghere return llvm::Error::success(); 91*fa1b4a96SJonas Devlieghere } 92