summaryrefslogtreecommitdiff
path: root/indra/newview/llluamanager.cpp
diff options
context:
space:
mode:
authorMnikolenko Productengine <mnikolenko@productengine.com>2024-02-23 16:57:00 +0200
committerMnikolenko Productengine <mnikolenko@productengine.com>2024-02-23 16:57:00 +0200
commit49785357e07f6309e2504b56829d9916f75168b2 (patch)
tree3c1c1f6f2ae167f806b47bf062e54bdb9838f1d7 /indra/newview/llluamanager.cpp
parent32bf9c7b7a9d2b2428b052d74389ec48ccc427cf (diff)
require() code clean-up
Diffstat (limited to 'indra/newview/llluamanager.cpp')
-rw-r--r--indra/newview/llluamanager.cpp89
1 files changed, 25 insertions, 64 deletions
diff --git a/indra/newview/llluamanager.cpp b/indra/newview/llluamanager.cpp
index 164738bc3b..671410d420 100644
--- a/indra/newview/llluamanager.cpp
+++ b/indra/newview/llluamanager.cpp
@@ -46,6 +46,7 @@ extern LLUIListener sUIListener;
#endif // ! LL_TEST
#include <boost/algorithm/string/replace.hpp>
+#include <filesystem>
#include "luau/luacode.h"
#include "luau/lua.h"
@@ -307,8 +308,7 @@ void LLLUAmanager::runScriptFile(LuaState& L, const std::string& filename, scrip
if (in_file.is_open())
{
- std::string text{std::istreambuf_iterator<char>(in_file),
- std::istreambuf_iterator<char>()};
+ std::string text{std::istreambuf_iterator<char>(in_file), {}};
auto [count, result] = L.expr(filename, text);
if (cb)
{
@@ -402,28 +402,6 @@ void LLLUAmanager::runScriptOnLogin()
#endif // ! LL_TEST
}
-
-bool is_absolute_path(std::string_view path)
-{
-#ifdef LL_WINDOWS
- // Must either begin with "X:/", "X:\", "/", or "\", where X is a drive letter
- return (path.size() >= 3 && isalpha(path[0]) && path[1] == ':' && (path[2] == '/' || path[2] == '\\')) ||
- (path.size() >= 1 && (path[0] == '/' || path[0] == '\\'));
-#else
- // Must begin with '/'
- return path.size() >= 1 && path[0] == '/';
-#endif
-}
-
-std::string join_paths(const std::string &lhs, const std::string &rhs)
-{
- std::string result = lhs;
- if (!result.empty() && result.back() != '/' && result.back() != '\\')
- result += '/';
- result += rhs;
- return result;
-}
-
std::string read_file(const std::string &name)
{
llifstream in_file;
@@ -431,20 +409,22 @@ std::string read_file(const std::string &name)
if (in_file.is_open())
{
- std::string text {std::istreambuf_iterator<char>(in_file), std::istreambuf_iterator<char>()};
+ std::string text {std::istreambuf_iterator<char>(in_file), {}};
return text;
}
return std::string();
}
-LLRequireResolver::LLRequireResolver(lua_State *L, std::string path) : mPathToResolve(std::move(path)), L(L)
+LLRequireResolver::LLRequireResolver(lua_State *L, const std::string& path) : mPathToResolve(path), L(L)
{
lua_Debug ar;
lua_getinfo(L, 1, "s", &ar);
mSourceChunkname = ar.source;
- if (is_absolute_path(mPathToResolve))
+ mPathToResolve = std::filesystem::path(mPathToResolve).lexically_normal().string();
+
+ if (std::filesystem::path(mPathToResolve).is_absolute())
luaL_argerrorL(L, 1, "cannot require a full path");
std::replace(mPathToResolve.begin(), mPathToResolve.end(), '\\', '/');
@@ -457,7 +437,7 @@ LLRequireResolver::LLRequireResolver(lua_State *L, std::string path) : mPathToRe
if (status != ModuleStatus::FileRead)
return ResolvedRequire {status};
else
- return ResolvedRequire {status, std::move(resolver.mChunkname), std::move(resolver.mAbsolutePath), std::move(resolver.mSourceCode)};
+ return ResolvedRequire {status, resolver.mAbsolutePath, resolver.mSourceCode};
}
LLRequireResolver::ModuleStatus LLRequireResolver::findModule()
@@ -467,26 +447,24 @@ LLRequireResolver::ModuleStatus LLRequireResolver::findModule()
// Put _MODULES table on stack for checking and saving to the cache
luaL_findtable(L, LUA_REGISTRYINDEX, "_MODULES", 1);
+ // Check if the module is already in _MODULES table, read from file otherwise
LLRequireResolver::ModuleStatus moduleStatus = findModuleImpl();
if (moduleStatus != LLRequireResolver::ModuleStatus::NotFound)
return moduleStatus;
- if (is_absolute_path(mPathToResolve))
+ if (std::filesystem::path(mPathToResolve).is_absolute())
return moduleStatus;
- std::vector<std::string> lib_paths;
-
- lib_paths.push_back(gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, ""));
+ std::vector<std::string> lib_paths {gDirUtilp->getExpandedFilename(LL_PATH_SCRIPTS, "lua")};
- for (size_t i = 0; i < lib_paths.size(); ++i)
+ for (const auto& path : lib_paths)
{
- std::string absolutePathOpt = join_paths(lib_paths[i], mPathToResolve);
+ std::string absolutePathOpt = (std::filesystem::path(path) / mPathToResolve).u8string();
if (absolutePathOpt.empty())
luaL_errorL(L, "error requiring module");
- mChunkname = absolutePathOpt;
mAbsolutePath = absolutePathOpt;
moduleStatus = findModuleImpl();
@@ -500,16 +478,12 @@ LLRequireResolver::ModuleStatus LLRequireResolver::findModule()
LLRequireResolver::ModuleStatus LLRequireResolver::findModuleImpl()
{
- std::string possibleSuffixes[] = {".luau", ".lua"};
-
- size_t unsuffixedAbsolutePathSize = mAbsolutePath.size();
+ std::string possibleSuffixedPaths[] = {mAbsolutePath + ".luau", mAbsolutePath + ".lua"};
- for (auto possibleSuffix : possibleSuffixes)
+ for (auto suffixedPath : possibleSuffixedPaths)
{
- mAbsolutePath += possibleSuffix;
-
- // Check cache for module
- lua_getfield(L, -1, mAbsolutePath.c_str());
+ // Check _MODULES cache for module
+ lua_getfield(L, -1, suffixedPath.c_str());
if (!lua_isnil(L, -1))
{
return ModuleStatus::Cached;
@@ -517,15 +491,12 @@ LLRequireResolver::ModuleStatus LLRequireResolver::findModuleImpl()
lua_pop(L, 1);
// Try to read the matching file
- std::string source = read_file(mAbsolutePath);
+ std::string source = read_file(suffixedPath);
if (!source.empty())
{
- mChunkname = "=" + mChunkname + possibleSuffix;
mSourceCode = source;
return ModuleStatus::FileRead;
}
-
- mAbsolutePath.resize(unsuffixedAbsolutePathSize); // truncate to remove suffix
}
return ModuleStatus::NotFound;
@@ -533,17 +504,12 @@ LLRequireResolver::ModuleStatus LLRequireResolver::findModuleImpl()
void LLRequireResolver::resolveAndStoreDefaultPaths()
{
- if (!is_absolute_path(mPathToResolve))
+ if (!std::filesystem::path(mPathToResolve).is_absolute())
{
- std::string path = gDirUtilp->getDirName(mSourceChunkname);
- std::replace(path.begin(), path.end(), '\\', '/');
- path = join_paths(path, mPathToResolve);
- mAbsolutePath = path;
- mChunkname = path;
+ mAbsolutePath = (std::filesystem::path((mSourceChunkname)).parent_path() / mPathToResolve).u8string();;
}
else
{
- mChunkname = mPathToResolve;
mAbsolutePath = mPathToResolve;
}
}
@@ -558,9 +524,9 @@ static int finishrequire(lua_State *L)
lua_function(require, "require(module_name) : module_name can be fullpath or just the name, in both cases without .lua")
{
- std::string name = luaL_checkstring(L, 1);
+ std::string name = lua_tostdstring(L, 1);
- LLRequireResolver::ResolvedRequire resolvedRequire = LLRequireResolver::resolveRequire(L, std::move(name));
+ LLRequireResolver::ResolvedRequire resolvedRequire = LLRequireResolver::resolveRequire(L, name);
if (resolvedRequire.status == LLRequireResolver::ModuleStatus::Cached)
return finishrequire(L);
@@ -577,18 +543,13 @@ lua_function(require, "require(module_name) : module_name can be fullpath or jus
luaL_sandboxthread(ML);
{
- // now we can compile & run module on the new thread
- size_t bytecodeSize = 0;
- std::unique_ptr<char[], freer> bytecode {
- luau_compile(resolvedRequire.sourceCode.c_str(), resolvedRequire.sourceCode.length(), nullptr, &bytecodeSize)};
-
- if (luau_load(ML, resolvedRequire.chunkName.c_str(), bytecode.get(), bytecodeSize, 0) == 0)
+ if (lluau::loadstring(ML, resolvedRequire.absolutePath.c_str(), resolvedRequire.sourceCode.c_str()) == LUA_OK)
{
int status = lua_resume(ML, L, 0);
- if (status == 0)
+ if (status == LUA_OK)
{
- if (lua_gettop(ML) == 0)
+ if (lua_gettop(ML) == LUA_OK)
lua_pushstring(ML, "module must return a value");
else if (!lua_istable(ML, -1) && !lua_isfunction(ML, -1))
lua_pushstring(ML, "module must return a table or function");