Close source iterator when take limit is reached (#591)#593
Conversation
…591) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
|
The latest updates on your projects. Learn more about Vercel for GitHub. 1 Skipped Deployment
|
|
ℹ️ Recent review info⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (2)
🚧 Files skipped from review as they are similar to previous changes (2)
📝 WalkthroughWalkthroughTGocciaLazyTakeIteratorValue now closes its source iterator via CloseIterator(FSourceIterator) when the take limit is reached in both DoAdvanceNext and DoDirectNext. Tests were updated and added to verify closure behavior (return() called / closed flag), generator finally execution, non-closure when the source exhausts early, immediate closure for take(0), and propagation of return() errors. ChangesIterator Take Source Closure
Estimated code review effort🎯 2 (Simple) | ⏱️ ~10 minutes Possibly related PRs
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. Comment |
Benchmark Results407 benchmarks Interpreted: 🟢 9 improved · 🔴 367 regressed · 31 unchanged · avg -8.5% arraybuffer.js — Interp: 🔴 12, 2 unch. · avg -8.1% · Bytecode: 🟢 1, 13 unch. · avg +1.0%
arrays.js — Interp: 🔴 17, 2 unch. · avg -10.8% · Bytecode: 🟢 10, 9 unch. · avg +2.4%
async-await.js — Interp: 🔴 5, 1 unch. · avg -10.9% · Bytecode: 6 unch. · avg -0.7%
async-generators.js — Interp: 🔴 1, 1 unch. · avg -11.2% · Bytecode: 2 unch. · avg -0.9%
base64.js — Interp: 🔴 10 · avg -12.2% · Bytecode: 🟢 2, 8 unch. · avg +0.7%
classes.js — Interp: 🔴 24, 7 unch. · avg -7.6% · Bytecode: 🟢 8, 🔴 2, 21 unch. · avg +2.1%
closures.js — Interp: 🔴 11 · avg -10.3% · Bytecode: 🟢 3, 8 unch. · avg +2.2%
collections.js — Interp: 🔴 12 · avg -11.0% · Bytecode: 🟢 3, 9 unch. · avg +1.1%
csv.js — Interp: 🔴 13 · avg -10.4% · Bytecode: 🟢 3, 10 unch. · avg +0.6%
destructuring.js — Interp: 🔴 21, 1 unch. · avg -8.7% · Bytecode: 22 unch. · avg -0.7%
fibonacci.js — Interp: 🔴 8 · avg -12.0% · Bytecode: 🟢 3, 5 unch. · avg +1.9%
float16array.js — Interp: 🟢 3, 🔴 25, 4 unch. · avg -5.2% · Bytecode: 🟢 18, 🔴 4, 10 unch. · avg +10.2%
for-of.js — Interp: 🔴 6, 1 unch. · avg -5.5% · Bytecode: 🟢 1, 6 unch. · avg +1.7%
generators.js — Interp: 🔴 4 · avg -9.4% · Bytecode: 🔴 4 · avg -5.9%
iterators.js — Interp: 🔴 40, 2 unch. · avg -9.7% · Bytecode: 🟢 13, 29 unch. · avg +2.7%
json.js — Interp: 🔴 20 · avg -12.0% · Bytecode: 🟢 2, 🔴 9, 9 unch. · avg -3.1%
jsx.jsx — Interp: 🔴 20, 1 unch. · avg -7.2% · Bytecode: 🟢 2, 19 unch. · avg -0.3%
modules.js — Interp: 🔴 9 · avg -11.7% · Bytecode: 🟢 7, 2 unch. · avg +4.7%
numbers.js — Interp: 🔴 11 · avg -10.7% · Bytecode: 🟢 5, 🔴 2, 4 unch. · avg +0.7%
objects.js — Interp: 🔴 7 · avg -7.0% · Bytecode: 7 unch. · avg -0.8%
promises.js — Interp: 🔴 12 · avg -7.2% · Bytecode: 🟢 4, 8 unch. · avg +2.5%
regexp.js — Interp: 🔴 10, 1 unch. · avg -7.2% · Bytecode: 🟢 3, 8 unch. · avg +2.0%
strings.js — Interp: 🔴 19 · avg -11.1% · Bytecode: 🔴 7, 12 unch. · avg -2.2%
tsv.js — Interp: 🔴 9 · avg -9.2% · Bytecode: 🟢 1, 8 unch. · avg +0.1%
typed-arrays.js — Interp: 🟢 3, 🔴 15, 4 unch. · avg +1.6% · Bytecode: 🟢 15, 🔴 1, 6 unch. · avg +5.8%
uint8array-encoding.js — Interp: 🔴 16, 2 unch. · avg -17.6% · Bytecode: 🟢 4, 🔴 9, 5 unch. · avg -16.6%
weak-collections.js — Interp: 🟢 3, 🔴 10, 2 unch. · avg +1.8% · Bytecode: 🟢 5, 🔴 5, 5 unch. · avg +16.0%
Deterministic profile diffDeterministic profile diff: no significant changes. Measured on ubuntu-latest x64. Benchmark ranges compare cached main-branch min/max ops/sec with the PR run; overlapping ranges are treated as unchanged noise. Percentage deltas are secondary context. |
Suite TimingTest Runner (interpreted: 8,994 passed; bytecode: 8,994 passed)
MemoryGC rows aggregate the main thread plus all worker thread-local GCs. Test runner worker shutdown frees thread-local heaps in bulk; that shutdown reclamation is not counted as GC collections or collected objects.
Benchmarks (interpreted: 407; bytecode: 407)
MemoryGC rows aggregate the main thread plus all worker thread-local GCs. Benchmark runner performs explicit between-file collections, so collection and collected-object counts can be much higher than the test runner.
Measured on ubuntu-latest x64. |
test262 Conformance
Areas closest to 100%
Per-test deltas (+1 / -0)Newly passing (1):
Steady-state failures are non-blocking; regressions vs the cached main baseline (lower total pass count, or any PASS → non-PASS transition) fail the conformance gate. Measured on ubuntu-latest x64, bytecode mode. Areas grouped by the first two test262 path components; minimum 25 attempted tests, areas already at 100% excluded. Δ vs main compares against the most recent cached |
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 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 `@source/units/Goccia.Values.Iterator.Lazy.pas`:
- Around line 273-277: The normal completion path uses
CloseIteratorPreservingError which can suppress an iterator.return() exception;
replace calls to CloseIteratorPreservingError with CloseIterator when closing
after normal exhaustion in the lazy iterator (the branch that sets FDone := True
and returns CreateIteratorResult(...)) so that iterator.return() exceptions are
allowed to replace the final { done: true } result; update the same change for
the other normal-completion block handling FIndex/FLimit (also affecting the
code paths around FSourceIterator, FDone, CreateIteratorResult).
🪄 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: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: fe224075-4249-4907-890f-4df4123be5ec
📒 Files selected for processing (2)
source/units/Goccia.Values.Iterator.Lazy.pastests/built-ins/Iterator/prototype/take.js
CloseIteratorPreservingError swallows errors from iter.return(), but take exhaustion is a normal completion — errors should propagate per ES2024 §7.4.10. Switch to CloseIterator and add a test verifying TypeError propagation. Also rename existing test to encode close semantics in name. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Summary
CloseIterator(normal-completion variant) whenIterator.prototype.takereaches its limit, matching TC39 Iterator Helpers spec (IteratorClose(iterated, NormalCompletion(undefined))).DoAdvanceNextandDoDirectNextinTGocciaLazyTakeIteratorValue.Testing
New tests added
take closes the source when the limit is reachedtake closes source iterator when limit is reached.return()called on custom iterator when take limit hittake runs generator finally blocks when limit is reachedfinallyblock executes on take exhaustiontake does not close source when source is exhausted before limittake(0) closes source iterator immediatelytake propagates errors from return() on normal completionTypeErrorfrom.return()propagates per ES2024 §7.4.10Full suite
8955/8960 pass (5 pre-existing FFI library loading failures, unrelated).