feat(vm): populate debug.getinfo name/namewhat from the call site#290
Merged
Conversation
Contributor
Author
Review: feat(vm): populate debug.getinfo name/namewhat from the call siteReviewed for correctness, tests, conventions, and simplification. Verdict: LGTM, ship it. No blockers. What I verified
Conventions: all clean
Minor (non-blocking)
|
debug.getinfo(level, "n") previously hardcoded name == nil and never set
namewhat. The caller's call instruction already carries a compile-time
name hint ({:global, "F"}, {:local, "x"}, ...) — the same hint that powers
"attempt to call a nil value (global 'foo')" errors — but two gaps kept it
from reaching debug.getinfo:
- The interpreter's :call handler pushed a call_stack frame for :lua_closure
callees but routed :compiled_closure callees straight into Dispatcher.execute
without recording a frame. A top-level `function F() ... end; F()` therefore
ran with an empty call_stack, so getinfo had no name to report.
- call_stack frames stored only the textual name, not the hint tag needed to
classify namewhat.
Now the interpreter records a frame for compiled-closure calls too, frames
carry namewhat derived from the hint tag, and debug.getinfo reads the running
function's frame (the head of call_stack when a native callback executes) to
surface name/namewhat. Covers the global, local, upvalue, field, and method
call forms; calls with no hint (through a temporary, tail calls) report
name == nil / namewhat == "", matching PUC-Lua's unknown fallback.
Narrows the constructs.lua suite skip past the debug.getinfo block.
Plan: A44
Closes #279
The compiler's name_hint/2 only emits 3-tuple {:field, name, recv} and
{:method, name, recv} forms, so the 2-tuple {:field, _} / {:method, _}
clauses in hint_namewhat/1 were unreachable. The trailing catch-all still
handles any unexpected shape defensively.
70dbf0f to
aef0f5c
Compare
3 tasks
davydog187
added a commit
that referenced
this pull request
Jun 1, 2026
Merge main and rebuild the constructs.lua triage on top of it. The os stdlib (#289) and debug.getinfo name resolution (#290) both landed, so the debug.getinfo block (line 226), the os.time assignment (line 237), and the GLOB1 concat (line 248) all pass now and no longer need skipping. Empirically re-triaged constructs.lua against the current tree: the only remaining failures are the short-circuit harness (284..299, level=4 combination explosion exceeds the test timeout) and the checkload block (302..311, load() error messages do not contain the expected 'expected'/'too long' substrings). Replace the single 232..313 entry with these two narrowed, disjoint ranges. Drops the duplicate A43-os-stdlib.md plan (the os work shipped via A43-os-library.md / #289) and the debug.getinfo name pinning test (superseded by the tests #290 shipped on main). Plan: A26
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Goal
Make
debug.getinfo(level, "n")return a non-nilnameand a matchingnamewhat, so the issue repro passes:Success criteria
debug.getinfo(1, "n").name == "F"forfunction F() ... end; F()namewhatreportsglobal/local/upvalue/field/methodmatching the call site, and""when no name is knownconstructs.luaskip narrows past thedebug.getinfoblock (was225..313, now232..313)mix testand the lua53 suite stay greenChanges
The caller's call instruction already carries a compile-time name hint (
{:global, "F"},{:local, "x"}, ...) — the same hint that powersattempt to call a nil value (global 'foo')errors. Two gaps kept it from reachingdebug.getinfo::callhandler pushed acall_stackframe for:lua_closurecallees but routed:compiled_closurecallees straight intoDispatcher.executewithout recording a frame. A top-levelfunction F() ... end; F()therefore ran with an emptycall_stack, sogetinfohad no name to report.call_stackframes stored only the textual name, not the hint tag needed to classifynamewhat.This PR:
call_stackframe for compiled-closure calls in the interpreter (mirroring the existing:lua_closurepush), so the running function's name is always available.namewhatfield on each frame, derived byhint_namewhat/1inLua.VM.Executor.call_stackwhen a native callback executes) inLua.VM.Stdlib.Debugto surfacename/namewhat.No prototype/codegen change was needed: the call-site hint already lives on the instruction stream, which is the faithful PUC-Lua
getfuncnamemodel.Verification
Out of scope
getfuncnameruntime instruction walk for every form. We reuse the existing compile-time hint, which covers global / local / upvalue / field / method call sites.(t[expr])(), immediately-invoked anonymous closures) and functions reached by a tail call: these keepname == nil/namewhat == "", matching PUC-Lua's unknown fallback.name/namewhatfor the entry chunk and for native (C) functions inspected by value (debug.getinfo(fn, "n")).Closes #279