Skip to content

Commit

Permalink
feat: remove dependency on require resolver
Browse files Browse the repository at this point in the history
  • Loading branch information
sssooonnnggg committed Nov 26, 2024
1 parent ad54eba commit 088dddd
Show file tree
Hide file tree
Showing 6 changed files with 68 additions and 23 deletions.
10 changes: 7 additions & 3 deletions .vscode/launch.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@
],
"stopAtEntry": false,
"environment": [],
// "console": "externalTerminal",
"preLaunchTask": "CMake: build"
},
{
Expand All @@ -28,8 +27,13 @@
"${workspaceRoot}/tests/main.lua"
],
"stopAtEntry": false,
"environment": [],
// "console": "externalTerminal"
"environment": []
},
{
"name": "[Luaud] Attach",
"type": "cppvsdbg",
"request": "attach",
"processId": "${command:pickProcess}"
}
]
}
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ A debugger for Luau with debug adapter protocol(DAP) support.
|
├── luaud # A minimal Luau executable with debug support
├── extensions # VSCode extension for Luau debugger
└── tests # Tests with lua scripts
└── tests # Test lua scripts
```

## Usage
Expand Down
10 changes: 6 additions & 4 deletions debugger/src/debugger.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -53,8 +53,6 @@ bool Debugger::stop() {
closeSession();
server_->stop();
debug_bridge_.reset();

DEBUGGER_LOG_INFO("Debugger stopped");
return true;
}

Expand All @@ -69,8 +67,12 @@ void Debugger::onError(std::string_view msg, lua_State* L) {
}

void Debugger::closeSession() {
if (std::exchange(session_, nullptr) == nullptr)
DEBUGGER_LOG_INFO("Debugger already stopped");
if (session_ != nullptr) {
// FIXME: This is a workaround to avoid error message not being sent to the
// client.
std::this_thread::sleep_for(std::chrono::milliseconds(100));
}
session_ = nullptr;
}

void Debugger::registerProtocolHandlers() {
Expand Down
1 change: 1 addition & 0 deletions extensions/vscode/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -99,3 +99,4 @@ A debugger for Luau with debug adapter protocol(DAP) support.
- [x] Disconnect and reconnect
- [x] Print to debug console
- [x] Coroutine
- [ ] Multiply lua vm
2 changes: 1 addition & 1 deletion luaud/file_utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

namespace file_utils {
inline std::optional<std::string> readFile(const std::string& name) {
std::ifstream file(name, std::ios::binary);
std::ifstream file(name, std::ios::in);
if (!file)
return std::nullopt;

Expand Down
66 changes: 52 additions & 14 deletions luaud/luau_runtime.cpp
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
#include <array>
#include <filesystem>
#include <format>
#include <string>

Expand Down Expand Up @@ -48,31 +50,67 @@ static int finishrequire(lua_State* L) {
return 1;
}

static std::string normalizePath(lua_State* L, const std::string& path) {
std::filesystem::path input_path = path;
input_path = input_path.lexically_normal();
if (input_path.is_absolute())
return input_path.string();

lua_Debug ar;
lua_getinfo(L, 1, "s", &ar);
std::string source_path = ar.source;
if (source_path.empty())
return path;

if (auto type = source_path[0]; type == '=' || type == '@')
source_path = source_path.substr(1);

std::filesystem::path source_dir =
std::filesystem::path(source_path).parent_path();
std::filesystem::path normalized_path =
(source_dir / path).lexically_normal();
return normalized_path.string();
}

static int lua_require(lua_State* L) {
std::string name = luaL_checkstring(L, 1);
std::string module_path = luaL_checkstring(L, 1);
std::string normalized_path = normalizePath(L, module_path);
luaL_findtable(L, LUA_REGISTRYINDEX, "_MODULES", 1);

std::array suffixes{".luau", ".lua", "/init.luau", "/init.lua"};

std::string source_code;
std::string resolved_path;
for (const char* suffix : suffixes) {
resolved_path = normalized_path + suffix;

RequireResolver::ResolvedRequire resolved_require =
RequireResolver::resolveRequire(L, std::move(name));
lua_getfield(L, -1, resolved_path.c_str());
if (!lua_isnil(L, -1))
return finishrequire(L);

lua_pop(L, 1);

std::optional<std::string> source = file_utils::readFile(resolved_path);
if (source) {
source_code = source.value();
break;
}
}

if (resolved_require.status == RequireResolver::ModuleStatus::Cached)
return finishrequire(L);
else if (resolved_require.status == RequireResolver::ModuleStatus::Ambiguous)
luaL_errorL(L, "require path could not be resolved to a unique file");
else if (resolved_require.status == RequireResolver::ModuleStatus::NotFound)
if (source_code.empty())
luaL_errorL(L, "error requiring module");

lua_State* GL = lua_mainthread(L);
lua_State* ML = lua_newthread(GL);
lua_xmove(GL, L, 1);

// now we can compile & run module on the new thread
std::string bytecode = Luau::compile(resolved_require.sourceCode, copts());
if (luau_load(ML, resolved_require.chunkName.c_str(), bytecode.data(),
bytecode.size(), 0) == 0) {
std::string bytecode = Luau::compile(source_code, copts());
if (luau_load(ML, resolved_path.c_str(), bytecode.data(), bytecode.size(),
0) == 0) {
// NOTICE: Call debugger when file is loaded
auto* debugger =
reinterpret_cast<luau::debugger::Debugger*>(lua_getthreaddata(GL));
debugger->onLuaFileLoaded(ML, resolved_require.absolutePath, false);
debugger->onLuaFileLoaded(ML, resolved_path, false);

int status = lua_resume(ML, L, 0);

Expand All @@ -90,7 +128,7 @@ static int lua_require(lua_State* L) {

lua_xmove(ML, L, 1);
lua_pushvalue(L, -1);
lua_setfield(L, -4, resolved_require.absolutePath.c_str());
lua_setfield(L, -4, resolved_path.c_str());

// L stack: _MODULES ML result
return finishrequire(L);
Expand Down

0 comments on commit 088dddd

Please sign in to comment.