Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix lua_*upvalue() when upvalue names aren't in debug info #787

Merged
merged 2 commits into from
Jan 18, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion VM/src/lapi.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1285,10 +1285,12 @@ static const char* aux_upvalue(StkId fi, int n, TValue** val)
else
{
Proto* p = f->l.p;
if (!(1 <= n && n <= p->sizeupvalues))
if (!(1 <= n && n <= p->nups)) // not a valid upvalue
return NULL;
TValue* r = &f->l.uprefs[n - 1];
*val = ttisupval(r) ? upvalue(r)->v : r;
if (!(1 <= n && n <= p->sizeupvalues)) // don't have a name for this upvalue
return "";
return getstr(p->upvalues[n - 1]);
}
}
Expand Down
28 changes: 28 additions & 0 deletions tests/Conformance.test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -691,6 +691,34 @@ TEST_CASE("Debugger")
CHECK(stephits > 100); // note; this will depend on number of instructions which can vary, so we just make sure the callback gets hit often
}

TEST_CASE("NDebugGetUpValue")
{
lua_CompileOptions copts = defaultOptions();
copts.debugLevel = 0;
// Don't optimize away any upvalues
copts.optimizationLevel = 0;

runConformance(
"ndebug_upvalues.lua",
nullptr,
[](lua_State* L) {
lua_checkstack(L, LUA_MINSTACK);

// push the second frame's closure to the stack
lua_Debug ar = {};
REQUIRE(lua_getinfo(L, 1, "f", &ar));

// get the first upvalue
const char* u = lua_getupvalue(L, -1, 1);
REQUIRE(u);
// upvalue name is unknown without debug info
CHECK(strcmp(u, "") == 0);
CHECK(lua_tointeger(L, -1) == 5);
lua_pop(L, 2);
},
nullptr, &copts, /* skipCodegen */ false);
}

TEST_CASE("SameHash")
{
extern unsigned int luaS_hash(const char* str, size_t len); // internal function, declared in lstring.h - not exposed via lua.h
Expand Down
13 changes: 13 additions & 0 deletions tests/conformance/ndebug_upvalues.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
-- This file is part of the Luau programming language and is licensed under MIT License; see LICENSE.txt for details
-- This tests that the lua_*upval() APIs work correctly even with debug info disabled
local foo = 5
function clo_test()
-- so `foo` gets captured as an upval
print(foo)
-- yield so we can look at clo_test's upvalues
coroutine.yield()
end

clo_test()

return 'OK'