Skip to content

Iterator.prototype.take must IteratorClose the underlying iterator when the limit is reached #591

@frostney

Description

@frostney

Summary

Iterator.prototype.take must call IteratorClose on the underlying iterator when the take limit is reached on the normal completion path. Currently the limit-reached branch in DoAdvanceNext and DoDirectNext sets FDone := True and returns a done result without closing the source iterator.

Why

Per TC39 Iterator Helpers specification, when remaining reaches 0 the take helper executes IteratorClose(iterated, NormalCompletion(undefined)). Without this, generators and other resource-holding iterators used as the source of .take(n) won't have their finally blocks run until GC or an explicit .return() call.

Current behavior

function* gen() {
  try { yield 1; yield 2; yield 3; }
  finally { console.log("closed"); }
}
const arr = gen().take(1).toArray(); // prints [1], "closed" never logged

The Close method on TGocciaLazyTakeIteratorValue does close the source, but it is only invoked by explicit .return() calls or GC — not on the normal limit-reached path.

Expected behavior

When the take limit is reached, DoAdvanceNext/DoDirectNext should close the source iterator before returning the done result, so generator finally blocks and other cleanup run immediately:

const arr = gen().take(1).toArray(); // prints [1], then "closed"

Scope notes

  • File: source/units/Goccia.Values.Iterator.Lazy.pasTGocciaLazyTakeIteratorValue.DoAdvanceNext (line ~273) and DoDirectNext (line ~292)
  • Use CloseIteratorPreservingError(FSourceIterator) so a throwing Close doesn't mask the done result
  • Add a JS test verifying generator finally blocks run when the take limit is reached
  • Surfaced during review of Centralize FExecuting re-entrancy guard into TGocciaIteratorHelperValue (#581) #589; not a regression — pre-existing behavior

Metadata

Metadata

Assignees

No one assigned

    Labels

    engineTGocciaEngine: language semantics, ECMAScript built-ins, parser, interpreter, bytecode VMspec complianceMismatch against official JavaScript/TypeScript specification

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions