Skip to content

Commit

Permalink
feat: support userdata display
Browse files Browse the repository at this point in the history
  • Loading branch information
sssooonnnggg committed Dec 5, 2024
1 parent 90439b4 commit 8a2ebaf
Show file tree
Hide file tree
Showing 4 changed files with 80 additions and 31 deletions.
97 changes: 67 additions & 30 deletions debugger/src/internal/variable.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -119,24 +119,78 @@ void Variable::addFields(luau::debugger::VariableRegistry* registry,
if (!hasFields())
return;

if (isTable()) {
scope_ = isTable() ? Scope::createTable(L) : Scope::createUserData(L);
if (isTable())
scope_ = Scope::createTable(L);
else if (isUserData())
scope_ = Scope::createUserData(L);

if (registry->isRegistered(scope_))
return;
if (registry->isRegistered(scope_))
return;

lua_utils::StackGuard guard(L);
int value_idx = lua_absindex(L, -1);

// https://github.com/luau-lang/rfcs/blob/master/docs/generalized-iteration.md
if (luaL_getmetafield(L, value_idx, "__iter"))
addIterFields(registry, L, value_idx);
else if (isTable())
addRawFields(registry, L, value_idx);
}

auto [it, _] = registry->registerVariables(scope_, {});
auto& variables = it->second;
void Variable::addRawFields(luau::debugger::VariableRegistry* registry,
lua_State* L,
int value_idx) {
auto [it, _] = registry->registerVariables(scope_, {});
auto& variables = it->second;

lua_utils::StackGuard guard(L);
int value_idx = lua_absindex(L, -1);
lua_pushnil(L);
while (lua_next(L, value_idx)) {
variables.emplace_back(addField(L, registry));
lua_pop(L, 1);
}
}

lua_checkstack(L, 2);
lua_pushnil(L);
while (lua_next(L, value_idx)) {
variables.emplace_back(addField(L, registry));
lua_pop(L, 1);
void Variable::addIterFields(luau::debugger::VariableRegistry* registry,
lua_State* L,
int value_idx) {
auto [it, _] = registry->registerVariables(scope_, {});
auto& variables = it->second;

lua_pushvalue(L, value_idx);
int call_result = lua_pcall(L, 1, 3, 0);
if (call_result != LUA_OK) {
DEBUGGER_LOG_ERROR(
"[Variable::registryFields] Failed to call __iter for {}, error: {}",
name_, lua_tostring(L, -1));
return;
}

auto next = lua_absindex(L, -3);
auto state = lua_absindex(L, -2);
auto init = lua_absindex(L, -1);

lua_pushvalue(L, next);
lua_pushvalue(L, state);
lua_pushvalue(L, init);
while (true) {
if (LUA_OK != lua_pcall(L, 2, 2, 0)) {
DEBUGGER_LOG_ERROR(
"[Variable::registryFields] Failed to call __iter for {}, error: {}",
name_, lua_tostring(L, -1));
return;
}
if (lua_isnil(L, -2))
return;
variables.emplace_back(addField(L, registry));

// pop value
lua_pop(L, 1);

// prepare for next iteration
lua_pushvalue(L, next);
lua_pushvalue(L, state);
lua_pushvalue(L, -3);
lua_remove(L, -4);
}
}

Expand All @@ -151,21 +205,4 @@ Variable Variable::addField(lua_State* L, VariableRegistry* registry) {
return variable;
}

// bool Variable::getUserDataIterator() {
// //
// https://github.com/luau-lang/rfcs/blob/master/docs/generalized-iteration.md
// if (!luaL_getmetafield(L, value_idx, "__iter")) {
// // No iterator for userdata, just return
// return;
// }

// int call_result = lua_pcall(L, 0, 3, 0);
// if (call_result != LUA_OK) {
// DEBUGGER_LOG_ERROR(
// "[Variable::registryFields] Failed to call __iter for {}, error: {}",
// name_, lua_tostring(L, -1));
// return;
// }
// }

} // namespace luau::debugger
6 changes: 6 additions & 0 deletions debugger/src/internal/variable.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,12 @@ class Variable {
lua_State* L,
std::string_view name,
int level);
void addRawFields(luau::debugger::VariableRegistry* registry,
lua_State* L,
int value_idx);
void addIterFields(luau::debugger::VariableRegistry* registry,
lua_State* L,
int value_idx);
void addFields(luau::debugger::VariableRegistry* registry, lua_State* L);
Variable addField(lua_State* L, VariableRegistry* registry);
std::string preprocessInput(const std::string& value);
Expand Down
2 changes: 1 addition & 1 deletion extensions/vscode/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ A debugger for Luau with debug adapter protocol(DAP) support.
- [x] table with cycle reference
- [x] vector
- [x] function
- [ ] userdata
- [x] userdata
- [x] Set variables
- [x] Repl
- [x] Watch
Expand Down
6 changes: 6 additions & 0 deletions tests/main.lua
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,12 @@ local function test_variables()
}
table_with_circle.b.d = table_with_circle
table_with_circle.e.g = table_with_circle.b

local userdata = {}
setmetatable(userdata, { __iter = function(x)
return next, table_with_circle
end })

local bar_function = function() end
foo_string = "ghi"
print("Hello, World!")
Expand Down

0 comments on commit 8a2ebaf

Please sign in to comment.