refactor(geninterp): unify opcode lowering semantics#142
Conversation
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (5)
🚧 Files skipped from review as they are similar to previous changes (2)
👮 Files not reviewed due to content moderation or server errors (1)
📝 WalkthroughWalkthroughThe PR replaces legacy fusion lowering with a catalog, resolution, and composition pipeline, updates threaded interpreter handlers and ownership semantics, strengthens generator validation, and adds exact-versus-fused runtime equivalence tests and contributor documentation. ChangesFusion lowering and threaded execution
Estimated code review effort: 5 (Critical) | ~120 minutes Possibly related issues
Possibly related PRs
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Warning There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure. 🔧 ast-grep (0.44.1)interp/threaded.goast-grep timed out on this file Comment |
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #142 +/- ##
==========================================
- Coverage 27.76% 26.95% -0.82%
==========================================
Files 83 83
Lines 60416 59198 -1218
==========================================
- Hits 16776 15957 -819
+ Misses 42447 42024 -423
- Partials 1193 1217 +24 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
There was a problem hiding this comment.
Actionable comments posted: 2
🧹 Nitpick comments (2)
interp/interp_test.go (1)
1908-1927: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winDuplicated snapshot/live-refcount helpers across the three new sub-tests.
Each of the three new
t.Runblocks defines its ownsnapshottype and a nearly identicalrunclosure, all repeating the same live-refcount loop:live := 0 for _, rc := range i.rc[1:] { if rc > 0 { live += rc } }Additionally, factoring
runout as a closure shared across multiplecasesentries departs from every other multi-case test in this file, which inlines setup/execution/assertions directly inside eacht.Run(tt.name, func(t *testing.T) {...})(e.g. the"host call releases the consumed callable ref...","fused UPVAL_GET+CONST binop..."tables). As per coding guidelines,**/*_test.goshould "Inline test setup, execution, and assertions unless the documented exception in §6.8 applies" — please confirm this shared-helper pattern falls under that documented exception, since it's a new style relative to the rest of the file.At minimum, the duplicated live-refcount computation is worth consolidating.
♻️ Proposed dedup for the live-refcount computation
+func liveRefCount(i *Interpreter) int { + live := 0 + for _, rc := range i.rc[1:] { + if rc > 0 { + live += rc + } + } + return live +}Then each
runclosure becomeslive: liveRefCount(i).Also applies to: 1979-1996, 2045-2063
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@interp/interp_test.go` around lines 1908 - 1927, Consolidate the repeated live-reference counting from the three test cases into a shared liveRefCount test helper, then have each run closure use it when populating snapshot.live. Review the local snapshot/run helpers in the affected t.Run blocks and inline setup, execution, and assertions unless the project’s documented exception explicitly permits this shared closure pattern; preserve all existing snapshot fields and test behavior.Source: Coding guidelines
internal/cmd/geninterp/generate_test.go (1)
249-336: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚖️ Poor tradeoffThis subtest asserts private implementation shape rather than behavior.
uses role based lowering namesparses the generator's own sources and asserts exact struct field names/ordering (Lines 288-293) and the presence/absence of internal helper function names (Lines 295-318). This couples the test to internal structure rather than observable generator behavior, so ordinary refactors (renaming a helper, reordering a field) will break it even when generated output is unchanged.Consider narrowing this to behavior that matters (e.g., generated-output assertions like the neighboring compose subtests), or at minimum limiting it to the naming invariants you truly want to freeze.
As per coding guidelines: "Tests must follow
docs/coding-patterns.md§6 and assert behavior rather than private implementation shape."🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@internal/cmd/geninterp/generate_test.go` around lines 249 - 336, The subtest uses AST inspection in “uses role based lowering names” to freeze private type fields and helper names instead of validating behavior. Replace the exact struct-field and function presence/absence assertions with generated-output or other observable behavior assertions, retaining only naming invariants required by the public generator contract and preserving the existing compose/lower behavior checks.Source: Coding guidelines
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@internal/cmd/geninterp/validate.go`:
- Around line 97-103: Update validateStack so opcodes where typ.Pop and typ.Push
are both nil are skipped with continue rather than terminating validation. This
must allow later instructions in the same pattern to continue through the stack
checks while preserving existing behavior for effectful opcodes.
In `@interp/threaded.go`:
- Around line 10520-10522: The fused push overflow guard incorrectly checks
i.sp+1, causing false panics with one free stack slot and missing overflow when
the stack is full. Update the generator logic in overflowAt or the fused push
path in internal/cmd/geninterp/lower.go so the emitted guard checks the actual
second-write condition, using i.sp == len(i.stack), while preserving correct
overflow handling for both pushes.
---
Nitpick comments:
In `@internal/cmd/geninterp/generate_test.go`:
- Around line 249-336: The subtest uses AST inspection in “uses role based
lowering names” to freeze private type fields and helper names instead of
validating behavior. Replace the exact struct-field and function
presence/absence assertions with generated-output or other observable behavior
assertions, retaining only naming invariants required by the public generator
contract and preserving the existing compose/lower behavior checks.
In `@interp/interp_test.go`:
- Around line 1908-1927: Consolidate the repeated live-reference counting from
the three test cases into a shared liveRefCount test helper, then have each run
closure use it when populating snapshot.live. Review the local snapshot/run
helpers in the affected t.Run blocks and inline setup, execution, and assertions
unless the project’s documented exception explicitly permits this shared closure
pattern; preserve all existing snapshot fields and test behavior.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro Plus
Run ID: a71e2af3-f4be-4324-ab7a-4057e1761f85
📒 Files selected for processing (9)
docs/fusion.mddocs/guides/add-opcode.mdinternal/cmd/geninterp/generate.gointernal/cmd/geninterp/generate_test.gointernal/cmd/geninterp/lower.gointernal/cmd/geninterp/pattern.gointernal/cmd/geninterp/validate.gointerp/interp_test.gointerp/threaded.go
|
Review follow-up:
|
Changes Made
source,ref,index,call,scalar, andbranchRelated Issues
None.
Additional Information
Validation completed with:
make checkmake check-generatedThe final naming cleanup leaves generated
interp/threaded.gobyte-for-byte unchanged. The completed semantic refactor keeps all measured fusion benchmarks at0 B/opand0 allocs/op; the full benchmark comparison againstmainproduced a-2.12%geomean runtime change.Summary by CodeRabbit
Performance
Bug Fixes
Documentation