compiler: stamp node ids once, at compile time - #416
Merged
Conversation
`Lua.Parser.parse_chunk/1` stamped every node with a `meta.id`, and `Lua.Compiler.compile/2` then stamped the whole chunk again — it has to, because a chunk built with `Lua.AST.Builder` (or one carrying hand-built nodes spliced into a parsed one) arrives unstamped, and skipping the walk for an "already stamped" chunk would need a walk to prove. Only scope resolution and codegen read `meta.id`, so the parser-side pass was pure duplication. Dropping it leaves exactly one walk per compile and saves roughly 30% of parse time (~460us on a 32KB chunk), while keeping every compilation path — parsed, hand-built, or mixed — correctly numbered. Parsed chunks now come back with `meta.id` unset; ids are a compiler concern, established at the compiler's own boundary. Claude-Session: https://claude.ai/code/session_01BYHGFLoHBJAsUrTzjVp5nC
davydog187
force-pushed
the
perf/ids-single-walk
branch
from
July 27, 2026 19:58
a894de1 to
59f5d2c
Compare
This was referenced Jul 27, 2026
Merged
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.
Follow-up to #400. That PR keyed scope resolution and codegen by
meta.id, stamping ids inLua.Parser.parse_chunk/1and then again inLua.Compiler.compile/2— the second stamp is required for correctness (aLua.AST.Builderchunk, or a parsed chunk with hand-built nodes spliced in, arrives unstamped or partially stamped, and an "already stamped?" early-out would cost the very walk it saves). So every parsed chunk paid for two full AST walks.Only
Lua.Compiler.ScopeandLua.Compiler.Codegenreadmeta.id— nothing between parse and compile touches it (verified acrosslib/andwebsite/). That makes the parser-side pass pure duplication, so this drops it.Result
One walk per compile instead of two. Interleaved A/B (8 rounds × 20 iterations, min-of-rounds, comparing
parseagainstparse+ the removedIds.assign):api.lua(32 KB)strings.lua(13 KB)This is strictly better than both current
mainand pre-#400: every path that compiles still gets numbered exactly once, and the hand-built path that #400 fixed stays fixed.Behavior change
Lua.Parser.parse/1(andparse_raw/1,parse_structured/1,parse_chunk/1) now return chunks withmeta.idunset — ids are a compiler concern, established at the compiler's boundary. Node ids were introduced in #400 and have never shipped in a release (latest tag isv1.0.1, which predates it), so no published contract changes. Docstrings onLua.Parser.parse_chunk/1andLua.AST.Idsupdated to say where stamping happens and that it reassigns from scratch.test/lua/ast/ids_test.exsnow appliesIds.assign/1before asserting — including the idempotence test, which becomes the real property (assign(assign(c)) == assign(c)) rather than a statement about parser output.Validation
mix compile --warnings-as-errors,mix format --check-formatted: cleanmix test: 2651 passedmix test --include lua53: 2671 passed, 16 skippedhttps://claude.ai/code/session_01BYHGFLoHBJAsUrTzjVp5nC