fix: preserve weakrefs in iterative clone path past MAX_DEPTH#119
fix: preserve weakrefs in iterative clone path past MAX_DEPTH#119Koan-Bot wants to merge 4 commits into
Conversation
| SV *circ_rv = newRV_inc(*already); | ||
| av_store(tail, 0, circ_rv); | ||
| if (SvWEAKREF(current_ref)) | ||
| av_push(weakrefs, SvREFCNT_inc_simple_NN(circ_rv)); |
There was a problem hiding this comment.
Looks like we are introducing a boilerplate here
this would need to be factorize using an helper or a macro to make the code easier to read/maintain and avoiding x4 times the same block of code
There was a problem hiding this comment.
Addressed in the rebase — the repeated if (SvWEAKREF(...)) av_push(weakrefs, SvREFCNT_inc_simple_NN(...)) pattern is now factored into the CLONE_TRACK_WEAKREF(src, rv, weakrefs) macro (defined at line 44, near the other CLONE_* macros). All five call sites use the macro. One minor follow-up: the macro parameters aren't parenthesized at their use sites — not a problem today since all callers pass simple identifiers, but worth tightening for defensive style.
|
@Koan-Bot rebase |
Rebase: fix: preserve weakrefs in iterative clone path past MAX_DEPTHBranch Diff: 3 files changed, 133 insertions(+), 3 deletions(-) Review feedback was analyzed and applied. ChangesCompiles cleanly with no warnings.
Actions
CICI will be checked asynchronously. Automated by Kōan |
5b6b05b to
69f6a4e
Compare
|
@Koan-Bot rebase |
Rebase: fix: preserve weakrefs in iterative clone path past MAX_DEPTHBranch Diff: 3 files changed, 133 insertions(+), 3 deletions(-) Review feedback was analyzed and applied. Actions
CICI will be checked asynchronously. Automated by Kōan |
69f6a4e to
4740be8
Compare
4740be8 to
4a59f59
Compare
|
@Koan-Bot rr |
PR Review — fix: preserve weakrefs in iterative clone path past MAX_DEPTHSolid, well-scoped fix. The 🟢 Suggestions1. Macro missing parentheses around parameter uses (`Clone.xs`, L44-49)The 2. Comment says ~1250 but value depends on platform (`t/24-weakref-iterative.t`, L30)
Checklist
SummarySolid, well-scoped fix. The |
Rebase with requested adjustmentsBranch Changes applied
StatsActions performed
CI statusCI will be checked asynchronously. Automated by Kōan |
When cloning structures deeper than MAX_DEPTH, the iterative fallback in av_clone_iterative created new RVs via newRV_noinc without checking SvWEAKREF on the original reference. This caused weakened references in deeply nested single-element array chains to silently lose their weak status, becoming strong references in the clone. The same issue existed in sv_clone's MAX_DEPTH entry points for RV-to-AV and RV-to-HV — the RVs wrapping iteratively-cloned containers didn't preserve weakness. Add SvWEAKREF checks at all three sites: - av_clone_iterative chain-walking loop (chain links) - av_clone_iterative circular-ref and leaf-AV handlers - sv_clone MAX_DEPTH block (RV-to-AV and RV-to-HV entry points) Weak RVs are pushed to the deferred weakrefs array, matching the pattern used by the recursive path and rv_clone_iterative. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…cking Compiles cleanly with no warnings. --- - **Extracted repeated weakref-tracking pattern into `CLONE_TRACK_WEAKREF(src, rv, weakrefs)` macro** (defined near other `CLONE_*` macros). Replaced all 5 identical `if (SvWEAKREF(...)) av_push(weakrefs, SvREFCNT_inc_simple_NN(...))` blocks with a single macro call each, per reviewer request to factorize the boilerplate.
…sive style - **Parenthesized all macro parameter uses in `CLONE_TRACK_WEAKREF`** — wrapped `src`, `rv`, and `weakrefs` in parentheses at their use sites inside the macro body. This is defensive C macro style that prevents operator-precedence surprises if a caller ever passes an expression rather than a simple identifier, per the reviewer's suggestion about missing parenthesization.
e89f448 to
fc57054
Compare
install-with-cpm@v1 regressed on Perl 5.8-5.22 after a recent cpm update requiring Perl 5.24+. Bump to @v2 for action-based jobs and use direct `cpm install` in the Docker-based Linux matrix (where cpm is pre-installed). Matches the approach approved by @atoomic in PR garu#120. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
What
Weakened references inside deeply nested array chains (past MAX_DEPTH) now preserve their weak status when cloned.
Why
The iterative clone fallback (
av_clone_iterative) creates RVs vianewRV_noincwithout checkingSvWEAKREFon the original reference. This silently converts weak references to strong ones in the clone — a correctness issue that breaks refcount-based lifetime management for structures cloned past the recursion depth limit.The same issue existed at the sv_clone MAX_DEPTH entry points for RV-to-AV and RV-to-HV, where the wrapping RV didn't preserve weakness.
How
Added
SvWEAKREFchecks at three sites:av_clone_iterativechain-walking loop (chain links and circular-ref/leaf handlers)sv_cloneMAX_DEPTH block (RV-to-AV and RV-to-HV entry points)Weak RVs are pushed to the deferred
weakrefsarray for batch weakening at the end, matching the pattern used by the recursive path andrv_clone_iterative.Testing
New test file
t/22-weakref-iterative.t(8 subtests):make testclean)Quality Report
Changes: 3 files changed, 130 insertions(+), 3 deletions(-)
Code scan: clean
Tests: passed (OK)
Branch hygiene: clean
Generated by Kōan post-mission quality pipeline